devharness 0.9.6 → 0.9.7
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/build/command-recorder-relocation.test.d.ts +2 -0
- package/build/command-recorder-relocation.test.d.ts.map +1 -0
- package/build/command-recorder-relocation.test.js +76 -0
- package/build/command-recorder-relocation.test.js.map +1 -0
- package/build/command-recorder.d.ts +1 -0
- package/build/command-recorder.d.ts.map +1 -1
- package/build/command-recorder.js +19 -1
- package/build/command-recorder.js.map +1 -1
- package/build/config.d.ts.map +1 -1
- package/build/config.js +5 -2
- package/build/config.js.map +1 -1
- package/build/helpers/paths-relocation.test.d.ts +2 -0
- package/build/helpers/paths-relocation.test.d.ts.map +1 -0
- package/build/helpers/paths-relocation.test.js +200 -0
- package/build/helpers/paths-relocation.test.js.map +1 -0
- package/build/helpers/paths.d.ts +35 -0
- package/build/helpers/paths.d.ts.map +1 -1
- package/build/helpers/paths.js +35 -0
- package/build/helpers/paths.js.map +1 -1
- package/build/issue-tracker-relocation.test.d.ts +2 -0
- package/build/issue-tracker-relocation.test.d.ts.map +1 -0
- package/build/issue-tracker-relocation.test.js +193 -0
- package/build/issue-tracker-relocation.test.js.map +1 -0
- package/build/issue-tracker.d.ts.map +1 -1
- package/build/issue-tracker.js +20 -4
- package/build/issue-tracker.js.map +1 -1
- package/build/mcp-supervisor.js +4 -3
- package/build/mcp-supervisor.js.map +1 -1
- package/build/self-restart.d.ts +5 -1
- package/build/self-restart.d.ts.map +1 -1
- package/build/self-restart.js +35 -5
- package/build/self-restart.js.map +1 -1
- package/build/self-restart.test.js +61 -17
- package/build/self-restart.test.js.map +1 -1
- package/build/server-manager-relocation.test.d.ts +2 -0
- package/build/server-manager-relocation.test.d.ts.map +1 -0
- package/build/server-manager-relocation.test.js +115 -0
- package/build/server-manager-relocation.test.js.map +1 -0
- package/build/server-manager-root-rebind.test.d.ts +2 -0
- package/build/server-manager-root-rebind.test.d.ts.map +1 -0
- package/build/server-manager-root-rebind.test.js +158 -0
- package/build/server-manager-root-rebind.test.js.map +1 -0
- package/build/server-manager.d.ts +19 -0
- package/build/server-manager.d.ts.map +1 -1
- package/build/server-manager.js +98 -4
- package/build/server-manager.js.map +1 -1
- package/build/supervisor/pidfile.d.ts +33 -6
- package/build/supervisor/pidfile.d.ts.map +1 -1
- package/build/supervisor/pidfile.js +76 -14
- package/build/supervisor/pidfile.js.map +1 -1
- package/build/supervisor/pidfile.test.js +37 -1
- package/build/supervisor/pidfile.test.js.map +1 -1
- package/build/tools/config-tools.d.ts.map +1 -1
- package/build/tools/config-tools.js +5 -0
- package/build/tools/config-tools.js.map +1 -1
- package/build/utils/modal-detection-core.test.js +21 -17
- package/build/utils/modal-detection-core.test.js.map +1 -1
- package/docs/messages.md +11 -0
- package/package.json +1 -1
- package/plugin/skills/devharness/SKILL.md +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local server records derive from the state root, so `relocateRoot` has to
|
|
3
|
+
* re-read them: without it the map built at startup keeps serving the
|
|
4
|
+
* previous root's servers, and the next `saveState` writes those records into
|
|
5
|
+
* the new root's file.
|
|
6
|
+
*
|
|
7
|
+
* Global records come from ~/.devharness, which no relocation moves, so they
|
|
8
|
+
* survive the rebind untouched.
|
|
9
|
+
*
|
|
10
|
+
* The relocation runs through `relocateRoot` (the production transaction in
|
|
11
|
+
* paths.ts), not through a hand-registered resource, so a missing
|
|
12
|
+
* registration in ServerManager fails here rather than passing on test-only
|
|
13
|
+
* wiring.
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
16
|
+
import { spawn } from 'child_process';
|
|
17
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'fs';
|
|
18
|
+
import { tmpdir } from 'os';
|
|
19
|
+
import { dirname, join } from 'path';
|
|
20
|
+
import { setWorkingDirOverride, initializePaths, getOutputPath, relocateRoot } from './helpers/paths.js';
|
|
21
|
+
import { ServerManager } from './server-manager.js';
|
|
22
|
+
let rootA;
|
|
23
|
+
let rootB;
|
|
24
|
+
let localFileA;
|
|
25
|
+
let localFileB;
|
|
26
|
+
let globalFile;
|
|
27
|
+
let originalGlobalDir;
|
|
28
|
+
function persistedServer(id, cwd, pid = -1) {
|
|
29
|
+
return {
|
|
30
|
+
type: 'native',
|
|
31
|
+
id,
|
|
32
|
+
command: 'node -e "setInterval(() => {}, 60000)"',
|
|
33
|
+
cwd,
|
|
34
|
+
pid,
|
|
35
|
+
autoRun: false,
|
|
36
|
+
startedAt: '2026-08-19T00:00:00.000Z',
|
|
37
|
+
monitorPort: false,
|
|
38
|
+
watch: false,
|
|
39
|
+
watchPaths: [],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function writeServersFile(filePath, servers, monitoredPorts = []) {
|
|
43
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
44
|
+
writeFileSync(filePath, JSON.stringify({ version: 4, servers, monitoredPorts, pendingStartups: [] }, null, 2));
|
|
45
|
+
}
|
|
46
|
+
async function serverIds(manager) {
|
|
47
|
+
return (await manager.getStatus()).map(status => status.id).sort();
|
|
48
|
+
}
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
rootA = mkdtempSync(join(tmpdir(), 'devharness-sm-rebind-a-'));
|
|
51
|
+
rootB = mkdtempSync(join(tmpdir(), 'devharness-sm-rebind-b-'));
|
|
52
|
+
// Isolate the global store the way server-manager-relocation.test.ts does -
|
|
53
|
+
// saveState() writes the global file unconditionally.
|
|
54
|
+
originalGlobalDir = process.env.CDP_TOOLS_DIR;
|
|
55
|
+
process.env.CDP_TOOLS_DIR = join(rootA, '__global__');
|
|
56
|
+
initializePaths();
|
|
57
|
+
setWorkingDirOverride(rootB);
|
|
58
|
+
localFileB = getOutputPath('servers.json');
|
|
59
|
+
setWorkingDirOverride(rootA);
|
|
60
|
+
localFileA = getOutputPath('servers.json');
|
|
61
|
+
globalFile = getOutputPath('servers.json', { global: true });
|
|
62
|
+
});
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
if (originalGlobalDir === undefined)
|
|
65
|
+
delete process.env.CDP_TOOLS_DIR;
|
|
66
|
+
else
|
|
67
|
+
process.env.CDP_TOOLS_DIR = originalGlobalDir;
|
|
68
|
+
initializePaths();
|
|
69
|
+
rmSync(rootA, { recursive: true, force: true });
|
|
70
|
+
rmSync(rootB, { recursive: true, force: true });
|
|
71
|
+
});
|
|
72
|
+
describe('relocateRoot: local server records follow the root', () => {
|
|
73
|
+
it('serves the new root\'s records and drops the old root\'s', async () => {
|
|
74
|
+
writeServersFile(localFileA, [persistedServer('a-only', rootA)]);
|
|
75
|
+
writeServersFile(localFileB, [persistedServer('b-only', rootB)]);
|
|
76
|
+
const manager = new ServerManager();
|
|
77
|
+
await manager.initialize();
|
|
78
|
+
expect(await serverIds(manager)).toEqual(['a-only']);
|
|
79
|
+
await relocateRoot(rootB);
|
|
80
|
+
expect(await serverIds(manager)).toEqual(['b-only']);
|
|
81
|
+
await relocateRoot(rootA);
|
|
82
|
+
expect(await serverIds(manager)).toEqual(['a-only']);
|
|
83
|
+
}, 20000);
|
|
84
|
+
it('serves nothing local when the new root has no records', async () => {
|
|
85
|
+
writeServersFile(localFileA, [persistedServer('a-only', rootA)]);
|
|
86
|
+
const manager = new ServerManager();
|
|
87
|
+
await manager.initialize();
|
|
88
|
+
await relocateRoot(rootB);
|
|
89
|
+
expect(await serverIds(manager)).toEqual([]);
|
|
90
|
+
}, 20000);
|
|
91
|
+
it('keeps global records, which no relocation moves', async () => {
|
|
92
|
+
writeServersFile(localFileA, [persistedServer('a-only', rootA)]);
|
|
93
|
+
writeServersFile(globalFile, [persistedServer('global-one', rootA)]);
|
|
94
|
+
const manager = new ServerManager();
|
|
95
|
+
await manager.initialize();
|
|
96
|
+
expect(await serverIds(manager)).toEqual(['a-only', 'global-one']);
|
|
97
|
+
await relocateRoot(rootB);
|
|
98
|
+
expect(await serverIds(manager)).toEqual(['global-one']);
|
|
99
|
+
}, 20000);
|
|
100
|
+
});
|
|
101
|
+
describe('relocateRoot: monitored ports follow the root', () => {
|
|
102
|
+
const portA = 39771;
|
|
103
|
+
const portB = 39772;
|
|
104
|
+
it('monitors the new root\'s ports and stops the old root\'s', async () => {
|
|
105
|
+
writeServersFile(localFileA, [persistedServer('a-only', rootA)], [
|
|
106
|
+
{ port: portA, level: 'inform', description: 'Server: a-only' },
|
|
107
|
+
]);
|
|
108
|
+
writeServersFile(localFileB, [persistedServer('b-only', rootB)], [
|
|
109
|
+
{ port: portB, level: 'inform', description: 'Server: b-only' },
|
|
110
|
+
]);
|
|
111
|
+
const manager = new ServerManager();
|
|
112
|
+
await manager.initialize();
|
|
113
|
+
const monitor = manager.getPortMonitor();
|
|
114
|
+
try {
|
|
115
|
+
expect(monitor.isMonitoring(portA)).toBe(true);
|
|
116
|
+
expect(monitor.isMonitoring(portB)).toBe(false);
|
|
117
|
+
await relocateRoot(rootB);
|
|
118
|
+
expect(monitor.isMonitoring(portB)).toBe(true);
|
|
119
|
+
expect(monitor.isMonitoring(portA)).toBe(false);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
await monitor.stopAll();
|
|
123
|
+
}
|
|
124
|
+
}, 20000);
|
|
125
|
+
});
|
|
126
|
+
describe('relocateRoot: a running server recorded under the new root', () => {
|
|
127
|
+
let child = null;
|
|
128
|
+
afterEach(() => {
|
|
129
|
+
if (child?.pid) {
|
|
130
|
+
try {
|
|
131
|
+
process.kill(child.pid, 'SIGKILL');
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Already gone - the test that owns it stopped it through ServerManager.
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
child = null;
|
|
138
|
+
});
|
|
139
|
+
it('takes the veto, so relocating away from that root is refused', async () => {
|
|
140
|
+
writeServersFile(localFileA, [persistedServer('a-only', rootA)]);
|
|
141
|
+
// A process this ServerManager never started, the way a record left by
|
|
142
|
+
// another session names one: its log fds pin rootB all the same.
|
|
143
|
+
child = spawn('node', ['-e', 'setInterval(() => {}, 60000)'], { stdio: 'ignore' });
|
|
144
|
+
await new Promise(resolve => child.once('spawn', () => resolve()));
|
|
145
|
+
writeServersFile(localFileB, [persistedServer('b-live', rootB, child.pid)]);
|
|
146
|
+
const manager = new ServerManager();
|
|
147
|
+
await manager.initialize();
|
|
148
|
+
await relocateRoot(rootB);
|
|
149
|
+
expect(await serverIds(manager)).toEqual(['b-live']);
|
|
150
|
+
await expect(relocateRoot(rootA)).rejects.toThrow(/b-live/);
|
|
151
|
+
expect(getOutputPath().startsWith(rootB)).toBe(true);
|
|
152
|
+
// Stopping it drops the veto, so the root can move again.
|
|
153
|
+
await manager.stopServer('b-live');
|
|
154
|
+
await relocateRoot(rootA);
|
|
155
|
+
expect(await serverIds(manager)).toEqual(['a-only']);
|
|
156
|
+
}, 20000);
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=server-manager-root-rebind.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-manager-root-rebind.test.js","sourceRoot":"","sources":["../src/server-manager-root-rebind.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -237,6 +237,25 @@ export declare class ServerManager {
|
|
|
237
237
|
*/
|
|
238
238
|
private killOrphanProcessesOnPort;
|
|
239
239
|
private waitForPortRelease;
|
|
240
|
+
/**
|
|
241
|
+
* A running NativeRunner has already opened its stdout/stderr file
|
|
242
|
+
* descriptors against the current root (NativeRunner.start()) - an
|
|
243
|
+
* OS-level fact no relocation can redirect. Registering this for as long
|
|
244
|
+
* as the server is tracked as running turns a relocation attempt into a
|
|
245
|
+
* rejection instead of a server silently logging into a directory nothing
|
|
246
|
+
* else points at any more.
|
|
247
|
+
*/
|
|
248
|
+
private registerRunningServerVeto;
|
|
249
|
+
/**
|
|
250
|
+
* Re-read local server records from the relocated root. `getServersFilePath`
|
|
251
|
+
* resolves through `getOutputPath`, so the map built at startup describes
|
|
252
|
+
* the previous root once the root moves; a list served from it names servers
|
|
253
|
+
* belonging to a directory nothing points at any more, and the next
|
|
254
|
+
* `saveState` writes those records into the new root's file. Every running
|
|
255
|
+
* server vetoes the relocation, so no local entry dropped here owns a live
|
|
256
|
+
* process. Global records live under ~/.devharness and stay put.
|
|
257
|
+
*/
|
|
258
|
+
private rebindToRoot;
|
|
240
259
|
/**
|
|
241
260
|
* Start a server
|
|
242
261
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../src/server-manager.ts"],"names":[],"mappings":"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"}
|
package/build/server-manager.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import * as fs from 'fs';
|
|
9
9
|
import * as net from 'net';
|
|
10
10
|
import { debugLog } from './debug-logger.js';
|
|
11
|
-
import { getOutputPath } from './helpers/paths.js';
|
|
11
|
+
import { getOutputPath, registerRootBound, unregisterRootBound } from './helpers/paths.js';
|
|
12
12
|
import { atomicWriteFile } from './atomic-write.js';
|
|
13
13
|
import { configManager } from './config.js';
|
|
14
14
|
import { ServerFileWatcher } from './server-watcher.js';
|
|
@@ -364,6 +364,15 @@ export class PortMonitor {
|
|
|
364
364
|
// ============================================================================
|
|
365
365
|
// Server Manager
|
|
366
366
|
// ============================================================================
|
|
367
|
+
/**
|
|
368
|
+
* Registry key for a running server's veto. The `server:` prefix keeps a
|
|
369
|
+
* server id from landing on the manager's own `server-manager` entry, which
|
|
370
|
+
* a bare id would replace - the registry is last-write-wins per name, so the
|
|
371
|
+
* collision would drop the rebind with nothing reported.
|
|
372
|
+
*/
|
|
373
|
+
function rootBoundServerName(serverId) {
|
|
374
|
+
return `server:${serverId}`;
|
|
375
|
+
}
|
|
367
376
|
export class ServerManager {
|
|
368
377
|
servers = new Map();
|
|
369
378
|
portMonitor = null;
|
|
@@ -378,6 +387,14 @@ export class ServerManager {
|
|
|
378
387
|
claims;
|
|
379
388
|
constructor(claimsStore = serverClaims) {
|
|
380
389
|
this.claims = claimsStore;
|
|
390
|
+
// Local server records derive from the state root, so a relocation leaves
|
|
391
|
+
// this map describing the previous root. registerRootBound is
|
|
392
|
+
// last-write-wins per name, so the rebind belongs to the most recently
|
|
393
|
+
// constructed manager - the one a tool call reaches.
|
|
394
|
+
registerRootBound({
|
|
395
|
+
name: 'server-manager',
|
|
396
|
+
rebind: () => this.rebindToRoot(),
|
|
397
|
+
});
|
|
381
398
|
}
|
|
382
399
|
/**
|
|
383
400
|
* Set the function used to check whether a CDP connection at a given
|
|
@@ -465,6 +482,7 @@ export class ServerManager {
|
|
|
465
482
|
watchPaths: server.watchPaths,
|
|
466
483
|
};
|
|
467
484
|
this.servers.set(server.id, managed);
|
|
485
|
+
this.registerRunningServerVeto(server.id);
|
|
468
486
|
// The process survived, but any watcher was tied to the previous
|
|
469
487
|
// ServerManager instance (e.g. before devharness's own supervisor
|
|
470
488
|
// restarted it) - re-establish it now.
|
|
@@ -865,6 +883,77 @@ export class ServerManager {
|
|
|
865
883
|
await debugLog('ServerManager', `Port ${port} still in use after ${maxAttempts} attempts`);
|
|
866
884
|
return false;
|
|
867
885
|
}
|
|
886
|
+
/**
|
|
887
|
+
* A running NativeRunner has already opened its stdout/stderr file
|
|
888
|
+
* descriptors against the current root (NativeRunner.start()) - an
|
|
889
|
+
* OS-level fact no relocation can redirect. Registering this for as long
|
|
890
|
+
* as the server is tracked as running turns a relocation attempt into a
|
|
891
|
+
* rejection instead of a server silently logging into a directory nothing
|
|
892
|
+
* else points at any more.
|
|
893
|
+
*/
|
|
894
|
+
registerRunningServerVeto(serverId) {
|
|
895
|
+
registerRootBound({
|
|
896
|
+
name: rootBoundServerName(serverId),
|
|
897
|
+
rebind: () => { }, // unreachable: this resource's own veto blocks every relocation while registered
|
|
898
|
+
veto: () => `managed server "${serverId}" is running and its log files cannot follow a relocated root`,
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Re-read local server records from the relocated root. `getServersFilePath`
|
|
903
|
+
* resolves through `getOutputPath`, so the map built at startup describes
|
|
904
|
+
* the previous root once the root moves; a list served from it names servers
|
|
905
|
+
* belonging to a directory nothing points at any more, and the next
|
|
906
|
+
* `saveState` writes those records into the new root's file. Every running
|
|
907
|
+
* server vetoes the relocation, so no local entry dropped here owns a live
|
|
908
|
+
* process. Global records live under ~/.devharness and stay put.
|
|
909
|
+
*/
|
|
910
|
+
async rebindToRoot() {
|
|
911
|
+
for (const [serverId, managed] of [...this.servers]) {
|
|
912
|
+
if (managed.global)
|
|
913
|
+
continue;
|
|
914
|
+
this.stopWatcher(managed);
|
|
915
|
+
unregisterRootBound(rootBoundServerName(serverId));
|
|
916
|
+
this.pendingStartups.delete(serverId);
|
|
917
|
+
this.servers.delete(serverId);
|
|
918
|
+
}
|
|
919
|
+
// Monitored ports are local-scope state (doSaveState writes them to the
|
|
920
|
+
// local file only), so they belong to the root that just went away.
|
|
921
|
+
await this.getPortMonitor().stopAll();
|
|
922
|
+
const persisted = await this.loadState(false);
|
|
923
|
+
for (const server of persisted.servers) {
|
|
924
|
+
const runner = createRunner(server.type || 'native', server.id);
|
|
925
|
+
runner.restore(server);
|
|
926
|
+
this.servers.set(server.id, {
|
|
927
|
+
id: server.id,
|
|
928
|
+
runner,
|
|
929
|
+
autoRun: server.autoRun,
|
|
930
|
+
monitorPort: server.monitorPort,
|
|
931
|
+
global: false,
|
|
932
|
+
watch: server.watch,
|
|
933
|
+
watchPaths: server.watchPaths,
|
|
934
|
+
});
|
|
935
|
+
// A record under this root can name a process another session started
|
|
936
|
+
// and left running; its log fds pin this root exactly as a server
|
|
937
|
+
// started here does, so it takes the same veto.
|
|
938
|
+
if (await runner.isRunning()) {
|
|
939
|
+
this.registerRunningServerVeto(server.id);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
for (const pending of persisted.pendingStartups) {
|
|
943
|
+
if (!this.servers.has(pending.serverId))
|
|
944
|
+
continue;
|
|
945
|
+
this.pendingStartups.set(pending.serverId, {
|
|
946
|
+
serverId: pending.serverId,
|
|
947
|
+
startedAt: new Date(pending.startedAt),
|
|
948
|
+
timeoutAt: new Date(pending.timeoutAt),
|
|
949
|
+
acknowledged: pending.acknowledged,
|
|
950
|
+
reason: pending.reason,
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
if (persisted.monitoredPorts.length > 0) {
|
|
954
|
+
await this.getPortMonitor().restoreFromState(persisted.monitoredPorts);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
868
957
|
/**
|
|
869
958
|
* Start a server
|
|
870
959
|
*/
|
|
@@ -915,6 +1004,7 @@ export class ServerManager {
|
|
|
915
1004
|
watchPaths: resolvedWatchPaths,
|
|
916
1005
|
};
|
|
917
1006
|
this.servers.set(serverId, managed);
|
|
1007
|
+
this.registerRunningServerVeto(serverId);
|
|
918
1008
|
if (watch) {
|
|
919
1009
|
this.startWatcher(managed, resolvedWatchPaths);
|
|
920
1010
|
}
|
|
@@ -1189,6 +1279,8 @@ export class ServerManager {
|
|
|
1189
1279
|
if (!managed) {
|
|
1190
1280
|
throw new Error(`Server "${serverId}" not found. Use list action to see servers.`);
|
|
1191
1281
|
}
|
|
1282
|
+
// Once stopped, its log fds are closed - nothing left to block a relocation.
|
|
1283
|
+
unregisterRootBound(rootBoundServerName(serverId));
|
|
1192
1284
|
// Clean up pending startup state
|
|
1193
1285
|
this.removePendingStartup(serverId);
|
|
1194
1286
|
// Stop watching and drop any queued/in-flight watch-restart state - a
|
|
@@ -1595,10 +1687,11 @@ export class ServerManager {
|
|
|
1595
1687
|
await this.stopServer(serverId);
|
|
1596
1688
|
}
|
|
1597
1689
|
else {
|
|
1598
|
-
// stopServer() (which also closes the watcher
|
|
1599
|
-
// when running - make sure a leaked
|
|
1600
|
-
// outlive removal either way.
|
|
1690
|
+
// stopServer() (which also closes the watcher and drops the relocation
|
|
1691
|
+
// veto) is only called above when running - make sure a leaked
|
|
1692
|
+
// watcher/veto/pending state can't outlive removal either way.
|
|
1601
1693
|
this.stopWatcher(managed);
|
|
1694
|
+
unregisterRootBound(rootBoundServerName(serverId));
|
|
1602
1695
|
}
|
|
1603
1696
|
// stopServer() already drops this server's port monitors when it runs, but
|
|
1604
1697
|
// removal has to cover the not-running path too - an orphaned block-level
|
|
@@ -1699,6 +1792,7 @@ export class ServerManager {
|
|
|
1699
1792
|
watch: server.watch,
|
|
1700
1793
|
watchPaths: server.watchPaths,
|
|
1701
1794
|
});
|
|
1795
|
+
this.registerRunningServerVeto(server.id);
|
|
1702
1796
|
await this.claims.claim(server.id, server.cwd, server.global);
|
|
1703
1797
|
await debugLog('ServerManager', `Adopted server started elsewhere: ${server.id}`);
|
|
1704
1798
|
}
|