@volter/world-runtime 3.0.102 → 3.0.103
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/dist/src/up-task.js +33 -12
- package/package.json +4 -4
- package/src/up-task.ts +24 -9
package/dist/src/up-task.js
CHANGED
|
@@ -14,6 +14,7 @@ export function superviseWorldUp(configId, options) {
|
|
|
14
14
|
});
|
|
15
15
|
let reply;
|
|
16
16
|
let failure;
|
|
17
|
+
let settled = false;
|
|
17
18
|
const cancel = (signal) => {
|
|
18
19
|
if (child.connected)
|
|
19
20
|
child.send({ type: 'cancel', signal }, error => { if (error)
|
|
@@ -23,8 +24,31 @@ export function superviseWorldUp(configId, options) {
|
|
|
23
24
|
const onTerm = () => cancel('SIGTERM');
|
|
24
25
|
process.on('SIGINT', onInt);
|
|
25
26
|
process.on('SIGTERM', onTerm);
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
// `up` is done the moment the owner answers: the caller settles on the reply and lets go of the owner (its channel
|
|
28
|
+
// and its handle), never waiting on its 'close'. 'close' waits for every inherited descriptor to end, and in a
|
|
29
|
+
// browser tab's kernel a service the owner started still held one: run 29 printed "returning: the World is up" at
|
|
30
|
+
// 7.54 s and this process stayed until the 10 s stop. With no reply, the owner's channel closing and its exit settle it.
|
|
31
|
+
const settle = () => {
|
|
32
|
+
if (settled)
|
|
33
|
+
return;
|
|
34
|
+
settled = true;
|
|
35
|
+
offSignal('SIGINT', onInt);
|
|
36
|
+
offSignal('SIGTERM', onTerm);
|
|
37
|
+
if (child.connected)
|
|
38
|
+
child.disconnect();
|
|
39
|
+
child.unref();
|
|
40
|
+
if (failure)
|
|
41
|
+
reject(failure);
|
|
42
|
+
else if (reply && 'error' in reply)
|
|
43
|
+
reject(new Error(reply.error));
|
|
44
|
+
else if (reply)
|
|
45
|
+
done(reply.instance);
|
|
46
|
+
else
|
|
47
|
+
reject(new Error(`World boot owner exited without a result (${child.signalCode ?? child.exitCode}); inspect \`volter-world status\` and the lifecycle log`));
|
|
48
|
+
};
|
|
49
|
+
child.on('error', error => { failure = error; if (!child.pid)
|
|
50
|
+
settle(); });
|
|
51
|
+
child.on('message', message => { reply = message; settle(); });
|
|
28
52
|
child.once('spawn', () => {
|
|
29
53
|
const request = { type: 'start', configId, options: { ...options, root: resolve(options.root ?? process.cwd()) } };
|
|
30
54
|
child.send(request, error => { if (error) {
|
|
@@ -33,17 +57,14 @@ export function superviseWorldUp(configId, options) {
|
|
|
33
57
|
child.disconnect();
|
|
34
58
|
} });
|
|
35
59
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
reject(new Error(reply.error));
|
|
43
|
-
else if (reply && code === 0)
|
|
44
|
-
done(reply.instance);
|
|
60
|
+
// No reply: every message the channel carried has been delivered once it disconnects; the owner's exit says why.
|
|
61
|
+
child.once('disconnect', () => {
|
|
62
|
+
if (reply)
|
|
63
|
+
return;
|
|
64
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
65
|
+
settle();
|
|
45
66
|
else
|
|
46
|
-
|
|
67
|
+
child.once('exit', settle);
|
|
47
68
|
});
|
|
48
69
|
});
|
|
49
70
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-runtime",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.103",
|
|
4
4
|
"description": "World configs for twins: boot named local runtimes, allocate ports, generate world.env/instance.json, and run apps against fake-key twin worlds.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
|
@@ -69,14 +69,14 @@
|
|
|
69
69
|
"node": ">=22.3"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
|
-
"@volter/world-core": "3.0.
|
|
73
|
-
"@volter/world-console": "3.0.
|
|
72
|
+
"@volter/world-core": "3.0.103",
|
|
73
|
+
"@volter/world-console": "3.0.98"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@electric-sql/pglite": "0.5.8",
|
|
77
77
|
"@electric-sql/pglite-pgvector": "0.0.9",
|
|
78
78
|
"@volter/world-access": "3.0.1",
|
|
79
|
-
"@volter/world-core": "3.0.
|
|
79
|
+
"@volter/world-core": "3.0.103",
|
|
80
80
|
"mongodb": "~6.20.0",
|
|
81
81
|
"pg-gateway": "0.3.0-beta.4",
|
|
82
82
|
"smol-toml": "^1.8.0",
|
package/src/up-task.ts
CHANGED
|
@@ -20,6 +20,7 @@ export function superviseWorldUp(configId: string, options: UpWorldOptions): Pro
|
|
|
20
20
|
});
|
|
21
21
|
let reply: UpTaskReply | undefined;
|
|
22
22
|
let failure: Error | undefined;
|
|
23
|
+
let settled = false;
|
|
23
24
|
const cancel = (signal: 'SIGINT' | 'SIGTERM') => {
|
|
24
25
|
if (child.connected) child.send({ type: 'cancel', signal }, error => { if (error) failure ??= error; });
|
|
25
26
|
};
|
|
@@ -27,19 +28,33 @@ export function superviseWorldUp(configId: string, options: UpWorldOptions): Pro
|
|
|
27
28
|
const onTerm = () => cancel('SIGTERM');
|
|
28
29
|
process.on('SIGINT', onInt);
|
|
29
30
|
process.on('SIGTERM', onTerm);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
// `up` is done the moment the owner answers: the caller settles on the reply and lets go of the owner (its channel
|
|
32
|
+
// and its handle), never waiting on its 'close'. 'close' waits for every inherited descriptor to end, and in a
|
|
33
|
+
// browser tab's kernel a service the owner started still held one: run 29 printed "returning: the World is up" at
|
|
34
|
+
// 7.54 s and this process stayed until the 10 s stop. With no reply, the owner's channel closing and its exit settle it.
|
|
35
|
+
const settle = () => {
|
|
36
|
+
if (settled) return;
|
|
37
|
+
settled = true;
|
|
37
38
|
offSignal('SIGINT', onInt);
|
|
38
39
|
offSignal('SIGTERM', onTerm);
|
|
40
|
+
if (child.connected) child.disconnect();
|
|
41
|
+
child.unref();
|
|
39
42
|
if (failure) reject(failure);
|
|
40
43
|
else if (reply && 'error' in reply) reject(new Error(reply.error));
|
|
41
|
-
else if (reply
|
|
42
|
-
else reject(new Error(`World boot owner exited without a result (${
|
|
44
|
+
else if (reply) done(reply.instance);
|
|
45
|
+
else reject(new Error(`World boot owner exited without a result (${child.signalCode ?? child.exitCode}); inspect \`volter-world status\` and the lifecycle log`));
|
|
46
|
+
};
|
|
47
|
+
child.on('error', error => { failure = error; if (!child.pid) settle(); });
|
|
48
|
+
child.on('message', message => { reply = message as UpTaskReply; settle(); });
|
|
49
|
+
child.once('spawn', () => {
|
|
50
|
+
const request: UpTaskRequest = { type: 'start', configId, options: { ...options, root: resolve(options.root ?? process.cwd()) } };
|
|
51
|
+
child.send(request, error => { if (error) { failure = error; if (child.connected) child.disconnect(); } });
|
|
52
|
+
});
|
|
53
|
+
// No reply: every message the channel carried has been delivered once it disconnects; the owner's exit says why.
|
|
54
|
+
child.once('disconnect', () => {
|
|
55
|
+
if (reply) return;
|
|
56
|
+
if (child.exitCode !== null || child.signalCode !== null) settle();
|
|
57
|
+
else child.once('exit', settle);
|
|
43
58
|
});
|
|
44
59
|
});
|
|
45
60
|
}
|