ai_co_discuss 0.3.84 → 0.3.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/runner/discussion_local.mjs +12 -4
- package/runner/discussion_service.mjs +11 -1
- package/web/modern.css +1 -1
- package/web/modern.js +30 -30
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ import { parseArgs } from 'node:util';
|
|
|
9
9
|
|
|
10
10
|
import { atomic_json } from './files.mjs';
|
|
11
11
|
import { acquire_lock } from './discussion_runner.mjs';
|
|
12
|
-
import { assert_shared_home, main as service_main, service_home, service_pid, service_ready, start_service } from './discussion_service.mjs';
|
|
12
|
+
import { assert_shared_home, main as service_main, service_home, service_pid, service_ready, service_stopped_by_user, start_service } from './discussion_service.mjs';
|
|
13
13
|
import { detect_python, local_settings } from './discussion_setup.mjs';
|
|
14
14
|
import { unlink_machine } from './remote_launch.mjs';
|
|
15
15
|
import { tone } from './discussion_tui.mjs';
|
|
@@ -20,6 +20,8 @@ const VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.u
|
|
|
20
20
|
const START_WAIT_MS = 15000;
|
|
21
21
|
const STOP_WAIT_MS = 25000;
|
|
22
22
|
const POLL_MS = 200;
|
|
23
|
+
// A service that exited without `service stop` (e.g. an old one adopted during an upgrade) is restarted at most this often.
|
|
24
|
+
const SERVICE_REVIVE_MS = 10_000;
|
|
23
25
|
const CONNECTION_TOKEN_BYTES = 32;
|
|
24
26
|
const LOCAL_HELP = `用法:codiscuss local open|start|status|stop [--json]
|
|
25
27
|
codiscuss local connect SITE [--setup-key KEY] [--no-open]
|
|
@@ -156,11 +158,17 @@ async function close_owned(child, owned_service, home) {
|
|
|
156
158
|
}
|
|
157
159
|
}
|
|
158
160
|
|
|
159
|
-
|
|
161
|
+
let revived_at = 0;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Start the service on an explicit request, or again when it exited without `service stop`, so replacement
|
|
165
|
+
* ownership stays local and an adopted service that exits later does not leave every room unattended.
|
|
166
|
+
*/
|
|
160
167
|
async function requested_service(home, status, owned_service) {
|
|
161
168
|
const path = join(home, 'local', 'start.request');
|
|
162
|
-
if (
|
|
163
|
-
|
|
169
|
+
if (existsSync(path)) unlinkSync(path);
|
|
170
|
+
else if (service_pid(home) || service_stopped_by_user(home) || Date.now() - revived_at < SERVICE_REVIVE_MS) return owned_service;
|
|
171
|
+
revived_at = Date.now();
|
|
164
172
|
const status_path = join(home, 'local', 'status.json');
|
|
165
173
|
try {
|
|
166
174
|
const service = await start_service(home);
|
|
@@ -32,6 +32,8 @@ const REMOTE_SYNC_MS = 3000;
|
|
|
32
32
|
const RELAY_RESTART_MIN_MS = 1000;
|
|
33
33
|
const START_WAIT_MS = 5000;
|
|
34
34
|
const STOP_WAIT_MS = 20_000;
|
|
35
|
+
// Left by `service stop` and cleared by any start: the local supervisor restarts a service that exited only without it.
|
|
36
|
+
const STOPPED_MARKER = 'service.stopped';
|
|
35
37
|
const REGISTRY_WAIT_MS = 5000;
|
|
36
38
|
// Housekeeping: logs above the limit keep only their newest part; a launch folder no room uses is removed once it is this old.
|
|
37
39
|
const SWEEP_MS = 6 * 60 * 60 * 1000;
|
|
@@ -744,6 +746,7 @@ export async function run_service(home, output = () => {}) {
|
|
|
744
746
|
/** Start the detached service once; an already running service is reused. */
|
|
745
747
|
export async function start_service(home) {
|
|
746
748
|
assert_shared_home(home);
|
|
749
|
+
rmSync(join(home, STOPPED_MARKER), { force: true });
|
|
747
750
|
const running = service_pid(home);
|
|
748
751
|
if (service_ready(home, running)) return { running: true, ready: true, pid: running, started: false };
|
|
749
752
|
mkdirSync(home, { recursive: true });
|
|
@@ -793,6 +796,11 @@ function read_persisted_env() {
|
|
|
793
796
|
} catch { return {}; }
|
|
794
797
|
}
|
|
795
798
|
|
|
799
|
+
/** Whether the user stopped the service on purpose, so the local supervisor must not bring it back. */
|
|
800
|
+
export function service_stopped_by_user(home) {
|
|
801
|
+
return existsSync(join(home, STOPPED_MARKER));
|
|
802
|
+
}
|
|
803
|
+
|
|
796
804
|
/** Ask the service to pause its runs and exit, then wait for its lock to be released. */
|
|
797
805
|
async function stop_service(home) {
|
|
798
806
|
if (!service_pid(home)) return { running: false };
|
|
@@ -865,7 +873,9 @@ export async function main(args = process.argv.slice(2), print = value => proces
|
|
|
865
873
|
switch (command) {
|
|
866
874
|
case 'run': return run_service(home);
|
|
867
875
|
case 'start': return print(await start_service(home));
|
|
868
|
-
case 'stop':
|
|
876
|
+
case 'stop':
|
|
877
|
+
atomic_json(join(home, STOPPED_MARKER), { stopped_at: Math.floor(Date.now() / 1000) });
|
|
878
|
+
return print(await stop_service(home));
|
|
869
879
|
case 'restart': await stop_service(home); return print(await start_service(home));
|
|
870
880
|
case 'status': return print(service_status(home));
|
|
871
881
|
case 'open': return print({ ...(await start_service(home)), opened: open_sites(home) });
|