We have been working on a Rust web framework that builds on top of lunatic, called submillisecond[0]. It's still in alpha and there is a lot to be figured out. Currently, we are attempting to build something like Phoenix LiveView[1] for it. One of the drawbacks of LiveView is that it requires a permanent connection to the backend, but because lunatic uses WebAssembly on the backend we can actually move part of the backend into the browser to allow for low-latency and offline use cases. Hopefully, you will be able to "just write" rust backend apps, but automatically get rich user experiences with offline support.
A big struggle for us has been the translation of some of the dynamic patterns from Erlang/Elixir to the strict type system of Rust. Also, Rust can't fully understand lunatic's processes, because the language was not designed with a concurrency model in mind where each unit of work gets their own heap memory. So there is some de/serialization going on when pushing data between processes.
As someone else mentioned, lunatic extends WebAssembly with a concurrency model, networking support, permission system, distributed compute, preemptive scheduling. But it's also a whole system for executing Wasm. So you can from your running wasm app load external .wasm files and spawn processes from them with specific constraints (memory/cpu usage, filesystem access, etc.). Someone in our community is building a system that uses submillisecond in combination with a dynamic router that dispatches workloads to external .wasm files. As you can probably tell, I'm super excited about all the possibilities and the future of lunatic.
I presume the bulk of the work there will be ensuring some kind of consistency between the backend database and whatever persistence layer one uses in the frontend (I presume something backed by `indexdb`)?
I ask, because I'm about to work on a full stack rust application (ie, even UI is handled by wasm) with gRPC, and I think I can learn things from your approach.
Do you have any web socket support? Web sockets that are serviced by actors make for a really nice programming model.
[0]: https://github.com/lunatic-solutions/submillisecond/pull/78
Isn't one of the main purposes of WebAssembly how it's like... portable/easy to run in different places? If you are in the backend, why not run a backend language like Rust in the first place + not introduce WebAssembly?
Here's the full context of the snippet you're questioning:
> One of the drawbacks of LiveView is that it requires a permanent connection to the backend, but because lunatic uses WebAssembly on the backend we can actually move part of the backend into the browser to allow for low-latency and offline use cases. Hopefully, you will be able to "just write" rust backend apps, but automatically get rich user experiences with offline support.
I'm reading/writing a fair amount of Python and C# at the moment, and the more I see async/await in use, the less I'm convinced by it as a language feature. Whilst the guidance seems reasonable on reading (e.g. [0]), the reality is that it increasingly becomes the norm to find code where most functions/methods are declared as async, and most implementations are littered with await.
So Lunatic's approach resonates. There again, as an Erlang fan, I'm pre-disposed to that concurrency model. So definitely not unbiased.
[0]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-g...
> This gives you the freedom to write simple blocking code, but the runtime is going to make sure it actually never blocks a thread if waiting on I/O.
It's more like Go or Ruby non-blocking fibers, where I/O primitives implicitly and automatically "yield" control to the event loop.
I don't know how that works, but I would guess that there's a big lookup table of such operations in the interpreter/compiler.
Thanks, yes, that's my point. I'm not convinced by async/await as a technique. I'm finding the "non-blocking fibers" approach much preferable in practice.
My expectation is if/when Java's Loom tech gains steam Microsoft will release its own pre-emptive thread pool into C# alongside async/await (again because they're different styles with different goals). Then everyone will be happy, ...right?
Yes, but that's not really the issue at hand. The issue is that async/await, as a particular _implementation_ of cooperative multi-tasking, has resulted in code bases dominated by async function declarations and bodies filled with awaits. Where, qualitatively, the volume of async/await code outweighs the actual need for concurrent/non-blocking execution.
>My expectation is if/when Java's Loom tech gains steam Microsoft will release its own pre-emptive thread pool into C# alongside async/await (again because they're different styles with different goals). Then everyone will be happy, ...right?
Maybe. That'll depend on whether they can address the viral nature of async. And it won't automatically get rid of the `xxxMethod/xxxMethodAsync` duality that has arisen. It'll also add yet more cognitive overload for developers ("should I use cooperative or pre-emptive multi-tasking here?").
--
EDIT: fixed spelling
What this project provides is what WASI and webassembly in general is currently missing: all the useful stuff like TCP networking, message passing between webassembly modules, filesystem access, transparent node distribution over a network, scheduling on an executor, permission configuration per process.
This is a first for the webassembly space if I am not mistaken. It will probably catch people by surprise who were trying to bring similar stuff to market of wasm on the server. I'm excited to see what lunatic brings on the table!
Lunatic provides this basic (but not trivial; it's complex) functionality through wasmtime. What lunatic offers is lots of functionality on top for wasm modules to actually do stuff. In general wasm modules by themselves, if not in the browser with access to the web APIs, are pretty useless since they are run in a sandbox and have no access to the outside world except for the imported functions you provide.
To be useful outside the browser, they need to do {network,filesystem} IO, which is the goal of the WASI standard [1]: to provide interfaces to external functionality. Lunatic says on the README it gives interfaces for message passing, filesystem, memory, network connections IO, etc.
WASM standards have actually stopped progressing since the Bytecode alliance took over the entire standard. It's very difficult to find who personally actually makes decisions in Bytecode alliance: going through lots of links and documents and github repos I see mostly employees of Fermyon and Fastly. It's important to notice the Bytecode alliance acts as if wasmtime is the only runtime that exists which is not the reality.
As a complete outsider and observer with no stake in the game, it seems like WASM is dead as a technology on the server unless initiatives like Lunatic take it forward with actual implementations instead of really basic product offerings without much functionality, or worse, vague promises, attempts at trademark registrations, registration of all wasm-related terms domains in most big TLDs. There's lots of incompetance, inexperience and/or malice in the WASM world and it's a shame.
At least before it all went to shit, WASM got full support on all browsers and we can enjoy it there!
[0] https://www.w3.org/TR/wasm-core-2/exec/runtime.html [1] https://wasi.dev/
I would not be surprised if the latter in particular introduces scalability issues due to making asymmetric communications more symmetric, but if people are having to introduce their own wheels, it may be better if the system provided it instead.
A bit later there was a company that has released generic java middleware called Voyager commercially. Among the other things it offered distributed actors as well. Unfortunately for whatever reason neither was a commercial success.
Another benefit is that you are not bound to a specific OS/arch. Lunatic lets you develop on macOs-arm64 and deploy on Windows-x64. Even container technologies widespread like Docker can't run on different CPU architectures. That proved to be a pain for people switching to the new M1 macs.
There are experimental or hobbyist VMs with great resource protection but that didn't receive a lot of attention, so they have all kinds of sharp edges. And there are mainstream VMs that all completely suck at resource protection even when it's one of the main goals of the project.
On the middle, with a good enough to be useful amount of protection, and receiving attention enough to be usable, there is basically only WASM.
I imagine there is an amount of javascript-like "I want whatever I have on the browser, so I'll have to learn less stuff" happening too. But I don't think it's as relevant, because there is much less to learn when picking a VM.