Thanks for being here, my name is Dan Phillips, and I am going to talk to you today about a
project of mine that I've been working on for a few years, and I've got to say I'm pretty
excited to see this room so full at 9 a.m. the day after all the parties, that's pretty
incredible. Yeah, so first thing, I'm going to start off just with a quick demo, just to kick
things off, and then I'll move into the talk. So, people here, everyone here is used web
assembly, yeah, for the most part, okay, good. How about Docker? Everyone used Docker? Yeah, of course,
okay, good. Okay, so I have this project called Boxer, yeah. And there's Boxed CLI, I'm just going
to kind of walk you through a quick example of what this can do, and you might see what it looks
like, how familiar it is to you. Cool, so with Boxer, what you can do is you can take a Docker file,
okay, a Docker file like this, this just runs a simple C program, that C program,
is this one, perfect for a demo, prints a hundred lines, and it uses something from the standard
library. This is very important. So, just to show you what this can do here, we'll do Box,
build Docker file, do a Box LS, you'll notice that this is a little big for that file that
I showed you, but we'll get into that in just a second. And then we'll do Box Run,
and then here's the real kicker, what do Box Run, and the same exact thing runs here.
Right? And how is that possible? That's possible because it's running the same thing in both environments.
Right? The, what was just executed was a container definition, but all in web assembly.
Right? So, I'm going to talk about this project, and I'm going to sort of talk about
web assembly broadly. Actually, this room, I don't need a ton of explanation, but I'll kind of
just go through it quickly. But quickly about me, my name's Dan Phillips, I work at a company called
Lupole Labs. We do a lot of different things, some Wasm stuff, but also we do some interesting
tech like live VM migration with no downtime, things like that. I work on this project called
Architects Architect.run, should check it out. It's very cool, unrelated to the stock.
On the internet, I mostly de-fil-a, de-a-nip-score-fil-a, on Twitter, X, whatever, and then
LinkedIn, GitHub, and I also run the Wasm Chicago Research Group. It's a systems engineering group where
we meet, read about things, and we have talks and stuff. So, if you're ever in Chicago,
please let me know. So, what is web assembly? It's going to go through this quickly.
Like I said, most of you in this room don't need this introduction, but just from the spec itself.
Web assembly is a safe port of a low-level execution format, which is designed for efficient
execution and compact representation. Safe sandboxed, it makes certain assumptions about security,
and then no assumptions about leg, which is or host. Virtual CPU is the best way to think
about it, right? Which can mean many things, but in this case, it just means a compilation target.
It's a virtual ISA. It uses a bytecode binary format. It's an abstract stack machine. Yep, and
what does that really mean? It's just another architecture. So, which is sort of the thrust of this
talk. And because it's another architecture, we have to treat it like a compilation target,
but there are some key differences, which is that it's virtualized. It needs a runtime,
but that does not necessarily mean it needs to be interpreted. It means you can also do things
like AOT and GIT and certain cases, and it's universal, right? So, most people outside of this room
and other places, when they hear about wasm, they usually say, oh, no, no, I don't see
very much front end stuff, right? And the interesting thing there is that, because it started off as
a sandbox execution in a sandbox execution environment, and it makes no assumption about languages
or host, it has things like extremely fast cold start times, and the nano to microseconds,
which depends on the size. And it's a universal compilation target. There's really nothing in the
spec about wasm being related to the web, or really being assembly, which is kind of a joke,
in the wasm community. So, then sort of comes in server-side wasm. I like to think of this as
cloud infrastructure's penicillin moment, where they saw these attributes of this technology,
and they could squint and say, hmm, that's interesting, that could be used in many other places,
right? Some people think of it like this, this sort of progression. We'll see if this is necessarily
true, and this is so far been born out. It's smaller, safer, faster, and much more universal.
Faster, having an asterisk, because many people say, well, it has a run time, so, therefore,
must be slower than native, that may or may not be true in most cases, but when it comes to things
like startup times, it can be much, much faster. I hate to use this quote again, but I feel like it's
required. This is the founder of Docker talking about this about five years ago. This got a lot of
VCs, but very excited back in 2019. And it's an interesting quote. He's sense sort of walked it back
saying, he didn't mean that it would replace Docker. He just means that this was a technology that
could have done many things back in the early days of LXC of containers. So, boxer,
one of the most important things that I think is missing in the web of some of the community now
is a developer experience that correctly abstracts away implementation details. I don't think
that, and I think many people would agree, I don't think that we've quite found the right
primitive for using WASM. So, this is a sort of, and when I say for using WASM, I mean as a general
purpose compute target, right? There are many, many different ways that people are using it.
At my company, we've built a thing called scale, scale that SH, which is a plug-in framework.
Back here, we've got my friend Eduardo from Dyliv, and they have an awesome plug-in framework. Also,
it's been really good in this sort of like polyglot plug-in space. But as far as general
purpose compute, there's a, no reason that it can't be a general purpose compute target,
much to many people's disagreements. And B, there's just not the correct tooling or abstractions yet.
So, Boxer kind of takes a first look at this. So, Boxer takes your program. We start with a Docker
definition, and then it builds a box. You can call it a WASM box, if you'd like. Very similar to what
you can think about in a container is we have a base layer. We have a virtualized file system
and system layer code. We have a compiled runtime. And then we have user source code.
Most importantly, the only way that these different layers can talk to each other are through
the process of imports and exports, which is fundamental to WASM modules and the separation of
concerns. So, how does it do this? So, there's quite a bit at the lower level, but basically
one thing that we think about with POSIX and with certain standards is interfaces. So, Boxer provides
these interfaces, live-see-like, just call interfaces. And that creates the first layer. And that's
sort of this from step here. You can do the same thing. So, once we have the virtualized
file system set up, you can basically do exactly what you would do in a Docker container, where
you bring in certain data, and it brings it into the guess. You can set the working directory,
and you can set the command. So, the WASM BFS, this is sort of the bedrock of all of this,
because for anyone who's done work with POSIX, you understand that everything is a file,
even though everything is not quite a file. It's good to start away with a file system, so you
can have things like file descriptors. So, the WASM BFS is sort of the bedrock of this. It's written
in Rust. So, obviously, it's incredible. It implements all of the Cisco's that you would find
in a POSIX file system, almost full POSIX semantics. Some key differences, though,
is some things like syncing, flushing, locking that you would find in normal file systems are
a little different, because of WASM's single-threaded nature by default, and a couple different
architecture patterns. So, if you see here, you can see this project. You can see all of the
standard exposed file system operations here. So, what that means is, if that's our base layer,
we have a couple caveats. This whole project has just been me working on this by myself, right?
So, I take that as you may. The POSIX surface area, we've reached about 70% and that means that we
have implemented every single lib-c call that is promised to be in POSIX, every single interface
at about 30% left. Networking. So, this is the interesting part. Networking, ENA Boxer,
ENA Boxer, Boxer, it WASM Box. Does work, you can do networking through relays on the host,
and in a distributed environment, you can do things like edge networking where you can specify
where the networking relay will be sent through. So, how that works could be an entirely different
talk. So, I'm not going to get into the details now, but if you want to talk about it, I would love to
talk to you about it after. Okay, the lower layers. The way that this all works and the way that we
can make this POSIX compatibility available is with a project called Markot. Markot kind of sets
up the substrate of the system layers that will be used in AWASM Box. If anyone here has done any work
with lib-cs, specifically muscle or g-lib-c, if you've ever looked at the internals, this will
look relatively familiar to you, because this is a muscle-based lib-c, which also brings in
g-lib-c functions that aren't in muscle, and it's kind of this Frankenstein of compatibility,
but what this does is this sets up the system layers for every single WASM Box. So, each layer
is virtualized where you have a file system networking, you have things like memory management,
process management, signals, and that is all defined here. So, this is a list of every single
function in POSIX, where it's implemented, and with notes about it. So, you can see that here,
we have this C code, which is wrapping the WASM VFS code, which is in Rust. The introp is actually
not as hard as you would think, but so this gives you file system compatibility, and then here
we have self-contained functions, which are C standard functions, and then all the way down here
is the remaining 30 percent of POSIX, which we are working on, which is things like process and
thread management, signals, and this is where things get really creative in a web assembly environment,
trying to make things like IPC work, like fork, like P threads, there's a lot that goes into that.
Each of these themselves could be a separate talk, also, be careful, okay. And, yeah, you're okay,
and so there's a lot here, but but basically know that there's about 30 percent remaining
before you can run any unmodified UNIX POSIX-based piece of code as you would on a native platform
in a WASM box. So, the big question is whether POSIX is the right way, so there are a lot of opinions
about POSIX, there are a lot of opinions about system design, yeah, in the web assembly community,
specifically there are some very heated discussions about this quite often, and it's anyone's
guess. I'm not too dogmatic about it myself. I think that when it comes to ABIs, they get crystallized
like they have in the Linux kernel over the last 30 years, and for better or worse, there are
trillions of dollars worth of software that are running on POSIX, that people don't like to rewrite
the lowest levels of their software, they like to run things on top of standards. So, yeah, whether
or not it's right, could also be another discussion if you want to have a beer later and
hash this out, I would love to do it with you. What POSIX defines though is, and I was just looking
at the IEEE spec about the day, is it's just interfaces. This is a very key distinction.
It's just interfaces. It defines behavior and interfaces. It does not say how you implement
that behavior, which is a very important distinction when it comes to building something
like a layer-based system for functionality, right? There's nothing in POSIX that necessarily
says you need to use something like a monolithic kernel. There's nothing that says you can't use a
microchernal or a unicarnal or no kernel at all, as long as the concepts are there and they can be
executed. So, that's a very important sort of line that I've taken with this project,
is that the interfaces will be fulfilled, but how they're fulfilled is quite different than
in other places. And then what is a process, right? There's an interesting thing about the tyranny
of the process in POSIX, just like the tyranny of file descriptors in POSIX. So, when you
squint, for those of you who have done work with Wasm, a executing Wasm module kind of looks like a
process, maybe. There was this idea early on in WebAssembly about nano processes and being able
to communicate between them that's kind of evolved into this thing called the component model.
But a Wasm module can communicate with other modules and externally by simple imports and
exports. And the only thing that that module knows about is what is exported to it and what it also
imports. This can set up a very different situation for things like IPC, communicating between
processes, making new processes, forking, and things like that. And it also does stuff like
remove massive amounts of overhead when it comes to communicating between different types of
execution that are happening on the same system. So, there's also a lot there. Mark Haatt,
this project handles the lower layers in Boxer. And that is, that could, this could be a
whole other talk also. But I'm happy to get into it with you later. If you want to catch up.
This is a picture that I had to actually be teammate for me. And it just kind of encapsulates the whole
idea. So, just getting into some of the metrics. When we say that WebAssembly Boxes with the same code
are smaller, safer, faster and more universal, there's a couple examples here. So, this is from
a talk I gave earlier this year, the Python conference, the same code. And this is, this is
excluding the container runtime. This is just the container images itself. And so, there's even
more to this. Standard Python container, when the age of AI, this has become the defector
language of the AI revolution somehow. And here we are. And so, Python images can be huge.
They can take seconds, maybe 30 seconds, maybe 40 seconds to actually start depending on
their dependencies. So, this is small one. And what's the security model? It's a container.
If you know how containers are implemented, it does a lot to hide the rest of the system
away. And it relies on having a kernel. It relies on having an operating system. It relies on
having C groups. There's a ton of back and forth about how this is implemented. I gave a similar
talk yesterday in the container room. And it's like, it's a completely different approach. But when
you start to be architecture level and then build from there, the defaults are very different.
So, the same code in a Wasm Box, six megabytes. If you pull out the source code and you snap
shot the system code, about five megabytes and 500 kilobytes for the source code, same app,
same exact app. Start of speed about 100 microseconds, depending on what's going on on the system.
And this can be also shut down more with things like wiser, which do snap shoting, and then you
can pre initialize memory in Wasm modules. And it's a completely different security paradigm.
So, the future. In a perfect world, we have a paradigm shift to completely composable universal
las and base operating system environments. That would be nice. It's probably not going to happen
overnight, but there are a lot of things that we can do if we get the primitive right. There
needs to be a way to deploy web assembly code without having to think about web assembly. That's
my personal opinion, and I'm sticking to it. Just like when you use Docker, or containers,
the vast majority of people who use Docker containers have no idea how secret works. Don't care,
right? So, you also get, like I showed in the first demo, you actually get true isomorphism.
Anyone who survived the Node.js hype of about 10 years ago remembers the sort of JavaScript I
can write JavaScript here. I can write JavaScript there. I can write JavaScript everywhere.
That turned out to not quite be true because the JavaScript is different in different environments.
This is actually isomorphic. You compile it once, run anywhere. That sounds familiar, unfortunately.
It turned into a, yeah, it turned into a compiled one to debug everywhere.
Yeah, the difference here is that this is actually the same code, and it's actually in different
environments, and it's not proprietary. It also doesn't bring a bunch of Java primitives into the run
time. If you want to talk more about run times, talk to my friend Eduardo, he knows more than me. He's
also a Java guy, so he can go back and forth with you on it. Yeah, so real isomorphism, very cool.
But it's also isomorphism across even more environments. That same code that I ran earlier on my
computer. I just showed you it ran in the browser. I could also take that same code and run it
on an embedded device. I could run it on a microcontroller. I could run it across operating systems,
across browsers. All of you likely have at least one wasm run time in your pocket, in your browser
right now. It's on every major browser, all of the four ones, the four big ones, and that's
really not going anywhere. There's this idea that true universality is more close at hand than
it ever has been. Then capabilities based on micro services. I talked about imports and exports.
If you've ever been to a container or Kubernetes conference, you'll see the vast array of the
ecosystem that does things like identity, that does things like security, that does things like
hardening the surface area for security boundaries on things that run containers, all of that.
All of that could be disrupted or could not be needed if you simply had secure stacks running
every single execution code and importing and exporting between those things in the same run time
or across run times. Web Assembly gives you that out of the box, without having to do anything,
because we started the architecture level and you have a secure execution stack for every
single piece of code that you want to run. This is very similar to plan 9. If anyone's
played with plan 9 or heard about this, the sort of dream that was almost realized,
giving every single execution environment its own CPU. Well, if you kind of zoom out a little bit,
that's exactly what Wasm does at a high level. Cool, thank you.
Excellent question, not yet, but we will. And how will we do that? I don't know, maybe you can
help me. Yeah, no, no, deal of is a tough one. Yeah, it's a tough one. So dynamic linking the
rub here is that from a guest, so in Web Assembly, I went fast through this, but we have
the concept of the host in the guest. From a single Wasm instance that is predefined,
Wasm is needs to be confirmed that it's Wasm prior to running by the run time.
So one of the things that is difficult now is spawning new processes from a process without
communicating with the host. So we have to create these host functions, which can do things like
mediate dynamic linking and loading, just like we do with forking and exacting. How that can work
is challenging, but not impossible with things like snapshot and pre initializing. And you can do
things like you can set up what's possible, so it'll probably start off by being like a very
limited set of dynamic linking that you can do. Yeah, other questions. So it's not there yet, but
if you sign up, I can show you. Yeah. Yeah. Yeah. Yeah. Yeah. And the master of the Wasm
last month, before building is the point that we've talked about. Yes.
The DCC, do you have a point like that? Yeah. So excellent question.
The Mark Haunt Library actually wraps GCC or Clang depending on what you're on, and then it
takes that and it converts it into Web Assembly for you, and you don't have to think about it.
So when you do box build, you can, so both GCC, so Clang, LVM, you can compile C2 as
pretty easily, but there are some exceptions. You can't compile it to like specific
architectures like this, so basically we stub out all of the lib C files, and then you,
it thinks that it's compiling to a native platform when it doesn't. Yeah. Yeah. Anybody else? Yeah.
So I think you have some that you can build into what I'm trying to say about, so this is
that you're multi-down nodes, the box itself is Wasm, right? Okay, but then the boxer will
will bundle a runtime with it, depending on what architecture that you're on, right? So the box itself
is portable. The runtime itself is not, right? So the idea there is you can take the same box
and move it around run times, right? If you want to do things like networking, you'll need to
bring in the specifics like you can plug in pieces to that runtime so that you can do things like
networking, but you can do that by moving it across different environments easily if you have
the runtime set up each one. Yeah, so a runtime is required everywhere. Yeah. Cool. Thanks,
that. Oh, wait, one more. Yeah. Yeah. Oh, good question. No, the runtime's in the browser are
pretty fast. There are some run times that are really fast on native and they're really small.
It depends. There's slight differences between them, but there are some slowdowns depending on
so each host is implemented in a specific language, right? And in the browser, you have to
communicate with, well, I've assembly through JavaScript, right? There's some inherent
unpredictable slowness there, right? With things like Wasm time or Wazeero in Go, it's a lot more
predictable depending on what performance you want. The faster asterisk is because people always say
it's virtualized how can it be faster? And I say, well, there's many things that are faster,
like startup times or orders of magnitude's faster. And if you're doing stuff like this where you
are virtualizing the interfaces for what are usually ciscalls, there is effectively no overhead
in terms of context switching like you would get with kernel, right? And so if you have something
with high like IOPS, then you multiply that a billion that is, you know, that is much, much faster
in terms of certain things. So it's a, it's an asterisk for that reason. Yeah. If you want to
talk more about it though, we can chat. All right, I should let my friend get up here.
So, time's up. Okay, yeah, thank you.