Files
scrypted/server/src/plugin/runtime/node-fork-worker.ts
2022-07-13 07:48:51 -07:00

70 lines
2.3 KiB
TypeScript

import { RuntimeWorkerOptions as RuntimeWorkerOptions } from "./runtime-worker";
import child_process from 'child_process';
import path from 'path';
import { RpcMessage, RpcPeer } from "../../rpc";
import { ChildProcessWorker } from "./child-process-worker";
import { getPluginNodePath } from "../plugin-npm-dependencies";
import { SidebandSocketSerializer } from "../socket-serializer";
import net from "net";
export class NodeForkWorker extends ChildProcessWorker {
constructor(pluginId: string, options: RuntimeWorkerOptions) {
super(pluginId, options);
const {env, pluginDebug} = options;
const execArgv: string[] = process.execArgv.slice();
if (pluginDebug) {
execArgv.push(`--inspect=0.0.0.0:${pluginDebug.inspectPort}`);
}
this.worker = child_process.fork(require.main.filename, ['child', this.pluginId], {
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
env: Object.assign({}, process.env, env, {
NODE_PATH: path.join(getPluginNodePath(this.pluginId), 'node_modules'),
}),
serialization: 'advanced',
execArgv,
});
this.setupWorker();
}
setupRpcPeer(peer: RpcPeer): void {
this.worker.on('message', (message, sendHandle) => {
if ((message as any).type && sendHandle) {
peer.handleMessage(message as any, {
sendHandle,
});
}
else if (sendHandle) {
this.emit('rpc', message, sendHandle);
}
else {
peer.handleMessage(message as any);
}
});
peer.transportSafeArgumentTypes.add(Buffer.name);
peer.addSerializer(net.Socket, net.Socket.name, new SidebandSocketSerializer());
}
send(message: RpcMessage, reject?: (e: Error) => void, serializationContext?: any): void {
try {
if (!this.worker)
throw new Error('worked has been killed');
this.worker.send(message, serializationContext?.sendHandle, e => {
if (e && reject)
reject(e);
});
}
catch (e) {
reject?.(e);
}
}
get pid() {
return this.worker.pid;
}
}