-
Notifications
You must be signed in to change notification settings - Fork 354
/
sandbox.ts
74 lines (66 loc) · 1.99 KB
/
sandbox.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import { ChildCommand, ChildMessage, ParentCommand } from '../interfaces';
import { ChildPool } from './child-pool';
import { Job } from './job';
const sandbox = <T, R, N extends string>(
processFile: any,
childPool: ChildPool,
) => {
return async function process(job: Job<T, R, N>, token?: string): Promise<R> {
const child = await childPool.retain(processFile);
let msgHandler: any;
let exitHandler: any;
await child.send({
cmd: ChildCommand.Start,
job: job.asJSONSandbox(),
token,
});
const done: Promise<R> = new Promise((resolve, reject) => {
msgHandler = async (msg: ChildMessage) => {
switch (msg.cmd) {
case ParentCommand.Completed:
resolve(msg.value);
break;
case ParentCommand.Failed:
case ParentCommand.Error: {
const err = new Error();
Object.assign(err, msg.value);
reject(err);
break;
}
case ParentCommand.Progress:
await job.updateProgress(msg.value);
break;
case ParentCommand.Log:
await job.log(msg.value);
break;
case ParentCommand.MoveToDelayed:
await job.moveToDelayed(msg.value?.timestamp, msg.value?.token);
break;
case ParentCommand.Update:
await job.updateData(msg.value);
break;
}
};
exitHandler = (exitCode: any, signal: any) => {
reject(
new Error('Unexpected exit code: ' + exitCode + ' signal: ' + signal),
);
};
child.on('message', msgHandler);
child.on('exit', exitHandler);
});
try {
await done;
return done;
} finally {
child.off('message', msgHandler);
child.off('exit', exitHandler);
if (child.exitCode !== null || /SIG.*/.test(`${child.signalCode}`)) {
childPool.remove(child);
} else {
childPool.release(child);
}
}
};
};
export default sandbox;