nats.rs icon indicating copy to clipboard operation
nats.rs copied to clipboard

Enable NATS Client to Run in WebAssembly

Open andrew-goldie opened this issue 10 months ago • 9 comments

Use case

Deploying lightweight NATS-based microservices on edge devices is a compelling architecture for many applications and probably represents the most significant architecture of the near future. Some immediate benefit is possible using Docker or natively-compiled apps, however a compile-once-run-anywhere approach would be, well... awesome. The promise of server-side WebAssembly combined with NATS would give the necessary building blocks.

Currently nats-async will not compile to WASM and this feature request is for it to do so.

Does the current state of WASI allow a review of nats.rs to compile to WASM, or is it just not there yet? Timeframe and dependencies aside, it would be great for this feature to be road-mapped.

Proposed change

Review code and dependencies to target WASM/WASI runtime.

Who benefits from the change(s)?

Programmers wanting to deploy lightweight NATS nodes across a range of hosts with a common compilation target.

Alternative Approaches

Solutions such as WasmCloud provide a way of connecting WASM targets with NATS, but the NATS providers sit outside the assembly and require the proprietary centralised architecture to construct solutions (setting aside the high-friction developer experience). I'm not aware of other innovations in this space.

andrew-goldie avatar Aug 22 '23 21:08 andrew-goldie

Hey! Thanks for filling in the issue.

There is some context in this discussion: https://github.com/nats-io/nats.rs/discussions/1045

Not impossible, but not trivial right now with the current state of WASI.

Jarema avatar Aug 23 '23 06:08 Jarema

Thanks, @Jarema. Understand the state of play with WASI not being implemented broadly nor even mature enough as a spec to do all the things we dream of. We are investing a lot in NATS-with-Rust (most enjoyable!) on existing platforms and will watch the emergence of WASM/WASI runtimes with interest.

andrew-goldie avatar Aug 25 '23 01:08 andrew-goldie

We also keep our eye on that topic, as it definately opens many possibilities.

Jarema avatar Aug 31 '23 07:08 Jarema

context in this discussion: https://github.com/nats-io/nats.rs/discussions/1045nats over websocket

States that websockets would be more amendable across runtimes.

Not impossible, but not trivial

I'd suggest to expose a trait that handles NATS transport. I haven't yet looked into this client, but there is precedence in python for such abstraction: https://github.com/nats-io/nats.py/pull/356

After this trait, the current impl becomes the default impl based on a default feature flag. If this feature was turned off, the crate would compile for wasm32-unknown by itself. Then some WASI based client, websocket clients etc. may require their own depencencies. Those other impls could live in this repo or outside, however maintainers desire.

The trait doesn't need to be 100% stable anyway (cf. async traits), but it would be nice if it turns out comparibly small and well designed.

How does that sound?

ahirner avatar Jan 16 '24 04:01 ahirner

Websockets is already our plan, so that could be a opportunity to work on the transport trait. That should be probably design together with more flexibility with picking TLS implementation to enable ESM32 usage and others.

Jarema avatar Jan 16 '24 10:01 Jarema

Isn't QUIC or a custom quic implementation like QUINN able to cover the majority of these needs + fallback?

wbaileyisla avatar Apr 06 '24 17:04 wbaileyisla

@wbaileyisla First of all, QUIC runs over UDP, so it does not change much in the WebAssembly story.

Secondly, NATS is based on TCP and does not (yet) support QUIC.

And most importantly NATS can also run over WebSockets, which are doable (if you for some reason want to do IO through WebAssembly) in WebAssembly.

Thats why WebSocket transport support is the most straightforward way here ;).

Jarema avatar Apr 06 '24 17:04 Jarema

https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API

Can we at least have nice things and support the webtransport? I saw you on the other quic thread some time ago, but I'm not sure I saw web transport ever talked about? Hope you're well!

wbaileyisla avatar Apr 06 '24 17:04 wbaileyisla

@wbaileyisla we're discussing here how to run nats.rs client in WebAssembly. And we can do it without any changes to nats-server itself, by just supporting WebSockets, which are also suported by nats-server.

Supporting WebTransport protocol is a whole different discussion, which probably is of scope of NATS v3, with new protocol, new tranport layer, etc. I doubt it makes sense.

However Quic does make sense and we do consider it. That, however, requires server support first and there is no proof so far that it would be quicker (beyond tls handshake).

Hopw youre doing well too!

Jarema avatar Apr 06 '24 17:04 Jarema