comlink icon indicating copy to clipboard operation
comlink copied to clipboard

Implement TransferHandlerMap.

Open Gaubee opened this issue 6 years ago • 5 comments

When I implemented some of the interfaces of WebRTC into WebWorker, I found that many things can only be transmitted in one direction. image

Therefore, if these types are registered in the child process, in the case of more and more types of registration, it may interfere with its operational efficiency. So I implemented this MapLike's TransferHandlerMap with three built-in types, both, serialize, and deserialize. It is fully compatible with the original usage.

Gaubee avatar Nov 08 '19 10:11 Gaubee

Hey @Gaubee. Sorry for the late reply here.

I don’t quite follow the use-case to be honest and it’s a significant amount of code. Let me try to explain what I think this is about: Some types can only be transfer from main thread to worker, but not the other way (or vice versa). If that is indeed the problem, I don’t think we need a change in Comlink. You can install a transfer handler on the main thread but not the worker to only allow transfer in one direction. Does that make sense? If not, can you elaborate a bit?

surma avatar Dec 06 '19 10:12 surma

If install a transfer handler on the main thread but not the worker, then the worker could not get type-safe object, I still need deserialize in the worker, right?

Gaubee avatar Dec 07 '19 13:12 Gaubee

Or let's focus on the example of WebRTC-WebWorker. First, I use diffrent transfrom code,

/// Master
Comlink.transformHanders.set('RTCPeerConnnection',{
  canHandle: (obj)=>obj instanceof RTCPeerConnnection,
  serialize: _serializeRTCPeerConnnection,
  deserialize: noop,
})
/// Worker
Comlink.transformHanders.set('RTCPeerConnnection',{
  canHandle: _=>false,
  serialize: noop,
  deserialize: _deserializeRTCPeerConnnection,
})

The problem is: In worker, there will have more and more canHandle: _=>false, those will make transform slow in some complex project. So If It is always CAN NO HANDLEABLE. why no just skip check?

But Yeah, I think there will have some better way to do this thing. for example, let's make new API:

/// Master
Comlink.transformHanders.registerSerialize(RTCPeerConnnection, 'RTCPeerConnnection', _serializeRTCPeerConnnection);

/// RTCPeerConnnection.prototype[Symbol.for('Comlink.Serialize')] = "RTCPeerConnnection";
/// serializeMap.set("RTCPeerConnnection", _serializeRTCPeerConnnection);
/// Worker
Comlink.transformHanders.registerDeserialize('RTCPeerConnnection',_deserializeRTCPeerConnnection)

If just use MAP BINDING, we can skip canHandle check, the serialize performace will be better.

const serializeBindingName = Symbol.for('Comlink.Serialize');
if( obj[serializeBindingName] ){
  return serializeMap.get(serializeBindingName)(obj);
}

Gaubee avatar Dec 07 '19 13:12 Gaubee

But event if I implement Class Binding Serialize I think people still need canHandle + serializeOnly of some special use case. bacause canHandle is more powerful.

Gaubee avatar Dec 07 '19 14:12 Gaubee

If you think the code of TransferHandlerMap is bloated, we can use redesign the api which is base on typescript, and generate a small amount of JS code. but maybe would break the API: You known, transformHanders is an map, We just use the .set(...) in most cases, but some people will use .get for .forEach, etc. So, there is why I implement TransferHandlerMap. I want maintain compatibility.

Gaubee avatar Dec 07 '19 14:12 Gaubee