paullouisageneau / datachannel-wasm

C++ WebRTC Data Channels and WebSockets for WebAssembly in browsers
MIT License
156 stars 27 forks source link

How about adding fibers/coroutines for DC's send method? #6

Closed jeffRTC closed 3 years ago

jeffRTC commented 3 years ago

I aware that we have an ongoing issue; however, I found a way to mimic threading like experience in browsers for DataChannel.send() method.

Fibers/Coroutines can archive concurrency without web workers. I'm unsure about implementation details.

http://js-coroutines.com/

If you look at this lib, it claims "Avoid the jank without having to resort to Worker threads or worry about glitches when you get your results back from them." which is quite sexy for me.

jeffRTC commented 3 years ago

Obviously, Round Robin based scheduling and multiplexing are another stuff to look at.

paullouisageneau commented 3 years ago

Coroutines are cool but they are just collaborative multitasking, in the sense that tasks are still processed one by one on the main thread, only with coroutines a task can pause to let the next one run. You can't pause from wasm code so it won't change that wasm code is limited to a single execution at a time.

There is a similar system with emscripten to mimic independant threads, however it has a cost, builds are bigger and performance is lower: https://emscripten.org/docs/porting/asyncify.html

jeffRTC commented 3 years ago

https://twitter.com/kripken/status/1218955129761611781

jeffRTC commented 3 years ago

I'm going to message him and see if he can add this new backend

jeffRTC commented 3 years ago

There is this ASYNCIFY_IMPORTS and ASYNCIFY_IGNORE_INDIRECT to reduce the overhead. Also -Oz can reduce the overhead.

The overhead would be at 5-10% if these options used else 50% as usual.

jeffRTC commented 3 years ago

If it's complex to add this, you can close this.

paullouisageneau commented 3 years ago

That's interesting, but I don't get what you want to add to the wrapper. This is something you should use in your own code.

jeffRTC commented 3 years ago

It turns out the dc.send method is a fire and forget style method means you can send many data without any interrupt; however, one should not fill the buffer completely and it's advised to listen for onbufferedamountlow to send more data.

Source: https://stackoverflow.com/questions/56327783/webrtc-datachannel-for-high-bandwidth-application

Would you be able to implement a re-try logic around onbufferedamountlow event?

I want be able to send many data without implementing even managing a custom queue my own.

Secondly, I believe as per my current knowledge (Still growing as I write :D), your API should have fiber based interface.

https://emscripten.org/docs/api_reference/fiber.h.html

A nice wrapper around it can be found here,

https://github.com/paladin-t/fiber

Feel free to correct me if I am wrong.

I still haven't got time to look into fibers more depth as we have an ongoing issue with Chrome

paullouisageneau commented 3 years ago

It turns out the dc.send method is a fire and forget style method means you can send many data without any interrupt; however, one should not fill the buffer completely and it's advised to listen for onbufferedamountlow to send more data.

Indeed, that's how the DataChannel API works.

Would you be able to implement a re-try logic around onbufferedamountlow event?

I want be able to send many data without implementing even managing a custom queue my own.

No, I'm not going to add custom logic around the wrapper as it's out of its scope. The goal of this wrapper is just to have an API identical to libdatachannel which is roughly equivalent to the browser WebRTC API. You can easily listen for the onbufferedamountlow event with the onBufferedAmountLow() method and send more data when it is triggered.

Secondly, I believe as per my current knowledge (Still growing as I write :D), your API should have fiber based interface.

https://emscripten.org/docs/api_reference/fiber.h.html

A nice wrapper around it can be found here,

https://github.com/paladin-t/fiber

Feel free to correct me if I am wrong.

I still haven't got time to look into fibers more depth as we have an ongoing issue with Chrome

I don't really get what you mean here. All methods basically return instantly just like the ones in the browser WebRTC API, so what for would you need fibers for in the API?

jeffRTC commented 3 years ago

Then we don't need fibers at all 😄