UNPKG

2.6 kBJavaScriptView Raw
1const { Cause, field, state, event, IO } = require("@cause/cause");
2
3
4const Process = Cause("Process",
5{
6 [field `pid`]: -1,
7 [field `killOnStart`]: false,
8
9 [field `send`]: null,
10 [field `child`]: null,
11 [field `kill`]: null,
12
13 [field `state`]: "initial",
14
15 [field `path`]: -1,
16 [field `args`]: [],
17
18 [event.out `Started`]: { pid: -1 },
19
20 [event.in `Kill`]: { },
21 [event.out `Finished`]: { exitCode: -1 },
22
23 [event.in `Message`]: { event: null },
24
25 [event.in `ChildStarted`]: { pid:-1, send:-1 },
26 [event.in `ChildMessage`]: { event: -1 },
27 [event.in `ChildExited`]: { pid: -1 },
28
29 [state `initial`]:
30 {
31 [event.on (Cause.Start)]: process => process
32 .set("child", IO.start(push => spawn(push, process)))
33 .set("state", "starting")
34 },
35
36 [state `starting`]:
37 {
38 [event.on `Kill`]: process => process
39 .set("killOnStart", true),
40
41 [event.on `ChildStarted`]: function (process, { send, pid })
42 {
43 const updated = process
44 .set("state", "running")
45
46 // FIXME: This should be IO!
47 .set("send", (...args) => send(...args))
48 .set("pid", pid);
49 const started = Process.Started({ pid });
50
51 return updated.killOnStart ?
52 [update(updated, Process.Kill), [started]] :
53 [updated, [started]];
54 }
55 },
56
57 [state `running`]:
58 {
59 [event.on `ChildMessage`]: onChildMessage,
60 [event.on `ChildExited`]: onChildExited,
61
62 [event.on `Kill`]: process => process
63 .set("state", "killing")
64 .set("kill", IO.start(push => spawn.kill(push, process.pid))),
65
66 [event.on `Message`]: (process, { event }) =>
67 (process.send(event), process),
68 },
69
70 [state `killing`]:
71 {
72 [event.on `ChildMessage`]: onChildMessage,
73 [event.on `ChildExited`]: onChildExited,
74
75 [event.on `Kill`]: event.ignore
76 },
77
78 [state `finished`]: { }
79});
80
81function onChildMessage(state, { event })
82{//console.log("ON CHILD MESSAGE", Object.getPrototypeOf(event).constructor.name);
83 return [state, [event]];
84}
85
86function onChildExited(state, { exitCode })
87{//console.log("ON CHILD EXITED", exitCode);
88 return [state.set("state", "finished"), Process.Finished({ exitCode })];
89}
90
91Process.isRunning = process =>
92 process.state === "running";
93
94Process.node = ({ path, args = [] }) =>
95 Process.create({ path: "node", args: [path, ...args] });
96
97module.exports = Process;
98
99const spawn = require("./spawn");