UNPKG

2.18 kBJavaScriptView Raw
1const Cause = require("@cause/cause");
2const { spawn, fork } = require("child_process");
3const { promisify } = require("util");
4const pstree = promisify(require("ps-tree"));
5const Process = require("./process");
6const legacy = require("@cause/cause/record");
7const { getUUID, getTypeWithUUID, deserialize, serialize } = require("@algebraic/type");
8
9
10
11module.exports = function fork_(push, { path, args })
12{
13 const process = path === "node" ?
14 fork(args[0], args.slice(1)) :
15 spawn(path, args, { stdio: [0, 1, 2] });
16 const { pid } = process;
17 const success = pid !== void 0;
18 const cancel = success && (() => kill(0, pid));
19
20 process.on("error", error => push(Process.ChildError({ error })));
21
22 // If we don't have a pid, we haven't actually started,
23 // we'll get an error about it.
24 if (success)
25 {
26 process.on("exit", exitCode => push(Process.ChildExited({ exitCode })));
27 process.on("message", message =>
28 push(Process.ChildMessage({ event: inferredDeserialize(message) })));
29
30 const send = event => process.send(inferredSerialize(event));
31 push(Process.ChildStarted({ pid, send }));
32 }
33
34 return cancel;
35}
36
37function inferredDeserialize({ isLegacy, UUID, serialized })
38{
39 if (isLegacy)
40 return legacy.deserialize(serialized);
41
42 return deserialize(getTypeWithUUID(UUID), serialized);
43}
44
45module.exports.inferredDeserialize = inferredDeserialize;
46
47function inferredSerialize(event)
48{
49 const type = Object.getPrototypeOf(event).constructor;
50 const UUID = getUUID(type);
51
52 if (typeof UUID !== "string")
53 return { isLegacy: true, serialized: legacy.serialize(event) };
54
55 return { UUID, serialized: serialize(type, event) };
56}
57
58module.exports.inferredSerialize = inferredSerialize;
59
60module.exports.kill = kill;
61
62function kill(push, pid)
63{
64 //console.log("KILLING " + pid);
65 return pstree(pid)
66 .then(children => children.map(({ PID }) => PID))
67 .then(children => ["-s", "SIGINT", pid, ...children])
68 .then(args => spawn("kill", args, { stdio:[0,1,2] }))
69 //.then(() => console.log("TOTALLY KILLED!"))
70 .catch(console.log);
71}