Spin – WebAssembly Framework
fermyon.com
fermyon.com
I myself am working on putting WebAssembly as a UI reconciliation engine.
1. You write your UI component spec (similar to React) in a language of your choice.
2. This compiles down to a WASM module, that knows how your state interplays with your UI tree.
3. A platform specific embedder can then write a tiny layer of renderer that translates commands from the WebAssmelby VM into native UI updates.
This way we can liberate UI programming from being too close to a platform and possibly could run on servers (damn fast SSR)
I'm attempting a proof of concept and I've logged my thoughts as I'm working through the project - https://github.com/joelewis/kwasm/blob/master/notes.txt
Github renders text files without line wrappings, so here's the raw link: https://raw.githubusercontent.com/joelewis/kwasm/master/note...
As you can assume, we are just as excited about all the places where we can run WebAssembly! That's a pretty intriguing idea, looking forward to seeing it evolve!
I see Spin as a small step towards that future of affordable cloud computing. Here's a twitter rant I wrote about the current state of affairs - https://twitter.com/vettijoe/status/1484507483788161026 (warning: Strong opinions ahead)
Someone mentioned about carbon footprint of increase due to containerization and the kubernetes culture during discussion about dagger [1]. Cloud cost, cloud waste and climate impact of current cloud computing setups are some biggest problem of this decade that are often ignored. I think webassembly and frameworks like these are the answer to that problem.
We have been talking about the efficiency/footprint thing a lot. So many things sit idle in the datacenter, consuming electricity without a good reason. WebAssembly is so fast to startup and shutdown that we think we can actually make a sizable dent into amount of compute required (and hence, amount of electricity consumed) if we can build this tooling right.
Spin took a first pass at this, but there is more we want to do to boost that efficiency even more! Hopefully in a few months I will be able to write a blog post with some progress on this.
And that's just it, most companies I've seen are content to ship code and deployments that are poorly architected (for performance and efficiency) and poorly performing.
I saw the same thing when I worked in the energy space. Effort is only expended when the ROI is big enough to justify it. And sometimes not even then! It's kind of depressing.
I actually think that the silly high cost of cloud infra can help bring about an appreciation of leaner runtimes (Go, Rust, etc) especially with cheap edge computing (cloud flare workers). That's an uphill battle though.
That said, I can envision a leaner orchestration model ( leaner than k8s) that strongly encourages more efficient computing. I'm excited to see how WASM fits into this, it could be a game changing tool for simplification.
> Github renders text files without line wrappings
Save it as .md not .txt and it should work
Is the workflow: Build app in rust, compile it down to WASM, and then run it on a server with wasmtime? I think I am missing some step.
Your intuition is mostly correct. Before anything, I strongly suggest you read this article on server-side WebAssembly — https://hacks.mozilla.org/2019/11/announcing-the-bytecode-al...
In short, when compiling to Wasm, you are building a binary that is agnostic of the operating system and CPU architecture it is going to run on, so it can be executed in lots of very different places (microcontrollers, Raspbery Pis, in the cloud). You can also use several VERY different programming languages, and interoperate between them (write a component in Rust, import it in a new component in JavaScript, and use those two from C# — this is an example for how the component model will (hopefully soon) enable cross-langauge interop in WebAssembly).
Among other benefits, the compact binary format (which makes it easy to distribute modules), the isolation sandbox, common compilation target.
Hope this is helpful!
Having an in-between bytecode layer allows you to build application architectures in rust that would not be possible when compiling directly to machine code. Hot reloading is a good example. Having the VM hold onto resources like tcp streams and file descriptors allows you to exchange the business logic without even breaking a tcp connection. Fine-grained sandboxing is another good example. Revoking filesystem access from just parts of your applications or limiting memory/cpu usage for each individual request[1] is something that is just impossible to do correctly without a vm managing it.
A less obvious benefit are the improvements to the developer experience, like compile times. Most of the dependencies (async executor, tcp stack, message passing, ...) are usually already part of the wasm runtime and don't need to be compiled/linked again. The rust compiler also seems to have a better time when it comes to generating .wasm executables instead of native ones. Most rust wasm apps I write compile much faster than equivalent native ones. Just because there is so much less for the compiler to do.
Many wasm runtimes, like lunatic, include an async scheduler and green threads/processes. This means that you get most of the benefits of async rust without needing to actually use async and worry about all the issues that come with it[2].
[0]: https://github.com/lunatic-solutions/lunatic
[1]: https://www.youtube.com/watch?v=8gwSU3oaMV8&list=PLdo4fOcmZ0...
Process separation and IPC natively using a library such as Qt is literally a few hundred lines of code.
"Hot reloading is a good example."
Again. You don't need WASM for hot reloading.
BTW not my words.
I'd think of it as plugins everywhere, like L7 proxies [1]. The code for a network filter could be reloaded in the server upon detection to a configuration change. I believe the startup mad dash is on to capture who is going to run the container runtimes, and host the plugin repositories.
So my guess is that Fermyon Technologies with Spin could be looking to follow the Vercel with NextJS model where everything will be open source and runnable from the development runtime, but there eventually will be features like Edge Functions [2] in five years that will only be available when you deploy to their hosted service. They'll likely work towards that with web services with Spin [3] and CMS with Bartholomew [4] for starters. Instead of everything linked together in a NodeJS app directly, your code will run from a WASM library in a sandbox.
But my guess about the Vercel model could be slightly wrong after checking out their solid founding team [5] -- the bios emphasize the WASM and Kubernetes worlds. The problem if it is something like the Docker model is that the standard will just be made with the big players like OpenContainer [6] and the enterprise business sold off [7], and/or folded into one of the cloud infra players (with the data centers).
[1] https://github.com/proxy-wasm/spec
[2] https://vercel.com/docs/concepts/functions/edge-functions
[4] https://github.com/fermyon/bartholomew
[5] https://www.fermyon.com/about
[6] https://opencontainers.org
[7] https://www.mirantis.com/blog/mirantis-acquires-docker-enter...
Browser containers may be better, but you share the same problem with app containers that you share physical memory and a kernel space.
Same type of challenges though, yes. Just a brand "new" secure sticker on the front, whatever that's actually worth.
Note this is a toy deployment, not actual content. Don't expect all the links to work or any content to be accurate or relevant :)
[1] https://spin.brian.dev/blog/2022-03-18-caddy-zero-downtime [2] https://github.com/bketelsen/wasmblog [3] https://github.com/fermyon/bartholomew
This is so cool! The Spin documentation website (https://spin.fermyon.dev) is also served by Spin itself, running on a Nomad cluster, with the same blogging engine mentioned here.
We're really looking forward to improving the rolling deployments, but it's really great seeing something like this live!
Now with Spin we are able to go beyond those first assumptions made with Wagi and explore exactly how far we can push it. It has been so much fun to explore how to have a Wasm module handle Redis events, or try out Python on Wasm for the very first time, or build a little CMS in Wasm... it feels like the early days of Docker all over again!
I have one nit about the article though. I think I haven't seen the claimed support for the Component Model anywhere in the code (other than naming the Wasm modules components), as its mainly based on the extent of WebAssembly Interface Types (WIT). Could anyone from the team give more info on where the Component Model proposal is actually used?
First, both Spin and the component model are in their early stages, but there are a few things I'd mention here:
- as you correctly pointed out, all "trigger" interfaces are based on WIT (https://github.com/bytecodealliance/wit-bindgen/blob/main/WI...), the new WebAssembly interface format, so a) building a WebAssembly binary that implements a trigger interface can be done pretty easily in languages with bindgen support, and b) extending Spin with a new trigger type can also be done by starting with the WIT interface (really early on this topic, but here's an example — https://spin.fermyon.dev/extending-and-embedding/)
- we want to add support for defining component dependencies, and dynamically linking them at runtime based on the environment.
- all "platform features" we want want to add to Spin will be initially based on host implementations for WebAssembly interfaces (you can see an early example of this in this PR — https://github.com/fermyon/spin/pull/165)
- we are closely following the tooling in the component model (https://github.com/bytecodealliance/wit-bindgen/pull/183) and will add support for natively executing actual components once that is available upstream.
Hope this is helpful!
I wonder how this will scale to large apps -- assumning thats one of the goals...if the target is just some kinda serverless cruft then maaaybe that can work, but I can already foresee a small config template hell unravelling in front of my eyes.
I might be missing something fundamental here, so take what I said with a pinch of salt.
This is not shifting the security responsibility from the firewall entirely — it's just an additional guard rail to ensure only allowed domains can be accessed. It does not mean setting proper firewall rules is no longer a concern, but just continuing WebAssembly's "deny by default" stance on accessing anything outside the sandbox.
We have not explored exactly how large scale apps will look like with Spin and WebAssembly — our initial target, at least in the beginning, is making sure building and running function-as-a-service(-like) applications is a great experience.
That's a great call-out regarding configuration and templates — we do have previous experience with "config template hell" from working in Kubernetes, Helm, CNAB, and other distributed systems platforms, so hopefully we can try to make things better!
Yes, "shifting" was a terrible choice of words on my side, sorry about that :)W hat I meant was, it gives developers more ways to manage outbound traffic -- which is both great but I wonder how the intersection of Ops and Devs handle this going forward because these things often become contention points at organizations (remember the enterprise proxies, etc.); let's see how this all plays out, but I'm glad devs now have more ways to [express and] manage these aspects of their apps.
This is trivial when they are clients of some other APIs, so about server side choices:
- domains, if reverse proxies / firewalls give them the IP of the client
- routes, by servicing the good URIs and 404 the bad ones (attacks more than honest mistakes)
- users, with many different authentication systems
- data, with validations.
The former points are traditionally more in the domain of the network infrastructure, the latter ones are for the application. I've seen all the possible combinations in the last 30 years.
You are correct, a lot of our team worked in the DeisLabs R&D team at Microsoft before joining Fermyon!
However, with the way things are currently going, are we using WebAssembly to reinvent the concept of Java applets? It all sounds very familiar. And if this is the case, will it run into similar problems?
Because it's lower level it's a more viable compile target for things that couldn't easily be compiled to Java, like C++ for example.
There are, of course, a lot of similarities between the Java or .NET runtimes and WebAssembly, and other comments made excellent points about the lower level nature of Wasm, or the isolation sandbox.
I would also point out that there are significantly more languages that either have support for compiling to WebAssembly today, or that have started adding support (in the last month alone there were initial announcements for Python, Ruby, and .NET, for example).
Like, I get the company wanting to sell services to people who might do wasm stuff, the whole quip about cross platform CLI? I don't think devs care, we have multiple tools for that already, thanks, generally I dont think CLIs are selling points to the "end user". If they are, small niche market with crossover with said devs.
The rest of it, been there done that, JVM, JavaBeans. The point of wasm was to allow better browser experiences, not build components in another esoteric runtime. In this regard Wasm is no different than any other scripting language, and this product is another dime a dozen 'enterprise offering', with all the usual pitfall that comes with. "Developers aren't Operators"? Ugh. "We want to chain you to your desk and churn out crappy feature after feature onto our already unmaintainable pile of slop"
Dislike.
And history repeats.
In all honesty, I think many of the concepts that we saw in early Java deserve to get another chance in a more language-agnostic ecosystem. I never did a lot of EJB, but CORBA/DCOM are definitely part of the inspiration for what Bytecode Alliance is doing with WebAssembly components.
Java sometimes gets a bad wrap (and so does .NET). Both ecosystems are full of amazing tooling and well-thought-out concepts. I think it's a great idea to look through these landscapes and ask, "Would these features be good additions to the WebAssembly ecosystem?"
I don't remember how I came up with the name - perhaps the "in" was for interface.
I'm not all that familiar with the Java ecosystem, but I seem to recall the CheerpJ people having examples for running Swing applications in the browser. (I don't know much about how their solution works, or whether it's open source.)
https://github.com/WebAssembly/interface-types/blob/main/pro...
Sorry for that rant, but I went into panic mode when I saw your question.
It reminds me of how everyone misunderstood smalltalk/OOP because they saw on it in terms of the existing paradigm. The misunderstanding pretty much cut us off from the real benefits of the idea because we got distracted writing classes and abstractions instead of passing around code with data across the network.
Maybe I'm off base here but my fear is that people see wasm new/cool/shiney and use it instead of JavaScript, and in the ensuing hype we lose the most valuable aspects of the technology (as partially demonstrated by Spin).
WIth the disclaimer that this is really early, and we don't have extensive benchmarks yet, there are a few things we are tracking for HTTP workloads (you can see the actual benchmark apps here — https://github.com/fermyon/spin/tree/main/crates/http/benche..., and the rendered results here — https://fermyon.github.io/spin-benchmarks/criterion/reports/):
- the response times — here are some benchmarks for requests that simulate 1 ms of work — https://fermyon.github.io/spin-benchmarks/criterion/reports/...
- the "cold" startup time — https://fermyon.github.io/spin-benchmarks/criterion/reports/...
Another disclaimer is that we have not focused on optimization work at all, so we expect to make significant improvements over the next few months.
On a lighthearted unscientific note: After getting absolutely bombarded with traffic today (5-10x normal, YAY!), we noticed: - No increased latency in responding to requests - Flat memory usage at 130MB per worker (we run Nomad) - Spiky CPU traffic (which is expected when starting and stopping Wasm modules hundreds of times a second), but never really over about 60% of the CPU on a small VM size on AWS - No Wasm downtime (though we did have a non-Wasm load balancer hiccup at about peak load, cause unknown)
We believe that the things that make WebAssembly attractive in the browser (compact binary, near-native speed, the sandbox isolation model) make it really compelling outside the browser, on the server.
> More than 20 programming tools vendors offer some 26 programming languages — including C++, Perl, Python, Java, COBOL, RPG and Haskell — on .NET.
From https://news.microsoft.com/2001/10/22/massive-industry-and-d...
> It has frontends for the following programming languages: C, Pascal, Modula-2, Occam, and BASIC.
> Maximum portability is achieved by using an intermediate language using bytecode, called EM. Each language front-end produces EM object files, which are then processed through several generic optimisers before being translated by a back-end into native machine code.
From https://en.wikipedia.org/wiki/Amsterdam_Compiler_Kit
> The hardware isolation provided by the TIMI allowed IBM to replace the AS/400's 48-bit IMPI architecture with the 64-bit RS64 architecture in 1995. Applications compiled on systems using the IMPI instruction set could run on top of the newer RS64 systems without any code changes, recompilation or emulation, while also allowing those applications to avail of 64-bit addressing
I think this is an excellent point — while we do try to give acknowledgement to the previous technology that paved the way for what we are doing (there are a few articles that treat microservices, containers, serverless https://fermyon.com/blog/index), I agree that we could do a better job at talking about programming languages and language runtimes.
Thanks for the suggestion!
While it might be slightly slower than running native code, I think that for certain users those are benefits that they can't overlook.
Naturally now they have to be packaged and sold as a new revolutionary idea for the newer generations.
And I wouldn't be surprised if some of those companies wouldn't be feeling like patent ways to compile and optized WebAssembly into native code, or anything else related to tooling.