websocket abstraction
ArtemGr opened this issue · 7 comments
In order to run in diverse environments (WASM / blockchains / kernels / hardware) the input-output needs to live behind an abstraction allowing for pluggable implementations. Let's implement such an abstraction for the Gun port.
A video that touches somewhat on why we might need an abstraction at that stage: https://youtu.be/vZ-fJl5BLmI
(So the nice thing is that we need to design a semi-dynamic plugin architecture that will likely be used in the rest of the port as well)
p.s. Abstraction allows also for specialization, such as the use of io_uring I/O
- Sub-crates for websocket implementations
- Plug in the tokio-tungstenite implementation
p.s. The modularity will likely help us with simulating various network conditions
The $314 bounty on this issue has been claimed at Bountysource.
@ArtemGr ah yes, this abstraction is called "DAM" in the GUN stack, the JS implementation already supports swappable multicast UDP, websockets, webrtc, etc. I'm glad you're already thinking this way for rust! If you want any further info on DAM, let me know - it is well designed & succeeded over the years at different challenges. RAD is the equivalent, but for storage swapping, while DAM is for networking.
"It's important that the application performs the choice. There is a temptation to do it inside the scheme itself, however this approach quickly runs into issues" ( https://www.reddit.com/r/Redox/comments/k5pkgc/an_approach_for_highlevel_dynamic_library/ ) - good point if we ever go into a dynamic assembly of components.
The way I see it now, a plugin library might provide some function pointers (and/or traits) which are swapped into the database, replacing default ones
High-level interface:
let mut gun = GunBuilder::new();
WebRTC::plug_into (&mut gun);
let gun = gun.build();
Low-level interface:
let mut gun = GunBuilder::new();
gun.functions.foobar = WebRTC::foobar;
let gun = gun.build();
I see this as an improvement in modularity compared to the usual Cargo "features" approach, which only supports the plugins which are explicitly known and maintained in the monolithic codebase. Overriding specific functions will also allow the developers to troubleshoot and/or explore improvements more easily.
I could take this although we will need to formalize a real API and check that the current test code works on the network.
I added plugin functionality and rewrote the tokio-tungstenite implementation in plain tungstenite.
let mut gun = GunBuilder::new();
plugins::tungstenite::plug_into(&mut gun);
let gun = gun.build();
This works. I also created files for websockets (low level) and websockets_wasm though both are unimplemented.
Rn the only function available is a "start" function for example:
let gun = gun.build();
gun.start(&["http://server1.com/gun", "http://server2.com/gun"]);
Though it doesn't do anything with the peers.
I've gotten really far with the websockets-tokio plugin. The plugin system is fully prepared to introduce new implementations. Think all that's left is to break it up into subcrates (rather than submodules).
All we have left to do here is add new implementations so I am closing this.
Can create new issues for the specific implementations.
Wow, this is so exciting to hear/see :D