Closed StNekroman closed 2 years ago
If Proxy
cannot be passed between two ports, then serializing it is the only way to go.
The only thing I can do is provide a parameter to help you with the serialization.
For functions, I think probably no RPC framework would support using functions as arguments, although serializing JavaScript functions is possible, but it almost certainly makes the code stink.
The newly added postMessage
option allows you to perform a deep copy of the request/response before it is sent, which should solve the Proxy
problem.
I tried adding serialization options, but in the end found them really unnecessary, postMessage
should solve most of the problems, because of structured clone.
Another option has been added: receiveMessage
, now you have full control over the format of the intermediate data.
Indeed, adding generic callback is good solution which should work for many use cases.
const rpcDiscordApi = createClient<DiscordApi>(proxyData.discordApiPort, {
postMessage: (port: MessagePort | Worker, request: IRequest<unknown>) => {
for (let i = 0; i < request.params.length; i++) {
if (NodeUtils.isProxy(request.params[i])) {
request.params[i] = JSON.parse(JSON.stringify(request.params[i]));
}
}
port.postMessage(request);
}
});
Works fine, serializes proxies to plain object.
Now regarding callbacks. Serializing them is evil, because callback must be executed in context (on the side) where it was created. Obviously because that lamdba can hold local references to another functions and local state. When I told about them I expected RPC-like behavior, where callback remains on the side where it was created and only triggered by backward event from RPC. But this is IPC already, not RPC. Which sounds out of scope of current project. But anyway... after additional thinking, I come to mind thta I don't need such callbacks at all. Becuase my requires is - to survive service restarts. Afte restart all existing lambdas in memory will be killed (no listener will be available after restart) So I will go with plain events: user did action on one side --> event has sent to another side --> another side is responsible to wire that event and perform callback action.
I have
I run it from inside VM2. VM2 replaces all external things with Proxy. So, instead of {prop1: 1} worker-threads will receive
instanceof Proxy
, which is not transferable between ports (not serializable) Any thougts?As dirty hack that cna be fixed by
JSON.parse(JSON.stringify())
But what if I want pass a function as callback? Like