comlink
comlink copied to clipboard
Are multiple worker possible?
I have multiple different workers:
app.ts
export const UserResolverWorker: UserResolverType = wrap<UserResolverType>(new Worker("./UserResolver.worker.js", {type:"module"}));
export const ConnectionsWorker: ConnectionsWorkerType = wrap<ConnectionsWorkerType>(new Worker("./Connections.worker.js", {type:"module"}));
UserResolver.worker.js
export const UserResolverWorker = {
getKeyPairs,
getPeerIdsByUid,
getUserByUid,
getPrivateUserByUid
};
expose(UserResolverWorker);
and connections.worker.js
const ConnectionsWorker = {
addMessage
};
expose(ConnectionsWorker);
I always get the error: Unhandled Rejection (TypeError): Cannot read property 'apply' of undefined
For this line because obj is
getKeyPairs: async (from, to) => {…}
getPeerIdsByUid: async uid => {…}
getPrivateUserByUid: async uid => {…}
getUserByUid: async uid => {…}`
but path contains only 0: "addMessage"
Were those workers switched by webpack during hot-reload (1.[hash].worker.js became 0.[hash].worker.js and vice versa) or can I only use one worker with comlink?
Multiple workers should be absolutely fine. Not sure what is going wrong here. Can you create a minimal test case?
tl;dr: This error happens because I tried to import from a *.worker.js file and used it in another worker.
Longer version: I wrote the flow between react, redux and worker in a test repository, and finally could provoke the error here: https://github.com/BudickDa/demo-worker/blob/master/src/modules/p2p/worker/P2P.ts
I have different modules, and each module has its own reducer, components and worker. Those workers should be able to share code. This is way I use the following "architecture":
- worker
- SharedCode.ts
- WorkerCode.worker.js
- index.ts
WorkerCode.worker packages the exported functions from SharedCode.ts into an object and exposes it. index.ts wraps the imported WorkerCode.worker and exports it to the app. SharedCode.ts can also be used by other workers or on the main thread.
WorkerCode.worker exports the packaged object for index.ts. My intelligent IDE or my intelligent self imported this object in another worker which messed everything up.
@surma The test case became a little bit bigger, because I tested some more different hypotheses, but the error is here: https://github.com/BudickDa/demo-worker/blob/07020f71959df1e2a45097ba9c68eacc3edea4d6/src/modules/p2p/worker/P2P.ts#L4
I think what happens is, that comlink is imported twice, which overwrites the api definition with the definition of a different worker. Maybe Comlink could throw an error if this is the case?
I'm also experiencing this issue. I'm able to instantiate and run a single worker type multiple times across the project, but cannot instantiate a worker with a different worker file. When we instantiate the second worker type, we get the error Unhandled Rejection (TypeError): Cannot read property 'apply' of undefined.
Ended up with the same issue
case MessageType.APPLY:
{
returnValue = rawValue.apply(parent, argumentList);
}
break;
rawValue is undefined and the parent is the wrong object, the one which is defined earlier.
Seems like whenever we sending message we are sending it to all workers.
Version 4.3.0 works without issue