Otherwise you are severely crippling yourself for no real gain. You're going to lag the hardware features by years if not decades, you're not going to get arch-specific optimizations as readily, and you're going to have huge startup costs. You're also stuck with sandbox restrictions that you've self-imposed, making it harder to do things that would have otherwise been trivial or needs to be re-invented.
You could maybe squint and claim you need a portable IR, but given there's only really 2 ISAs in widespread use (x86 & ARM) does that _really_ matter? Similarly you could claim cross-OS support, but again as there's only _really_ 2 OS's for each target (Windows/Linux for server, Android/iOS for mobile) does that _really_ matter? Critically does it matter to such a degree that you'd rather severely cripple your own app to get it instead of just compiling it 2, 3, or 4 times?
Once you get a _good_ solution to embedding untrusted code, you might find it turns out to be pretty useful.
No, process isolation does not work for us, because it does not scale well enough.
The point of Cloudflare Workers is to distribute your code across Cloudflare's entire edge network -- 154 locations and growing -- so that you can respond to requests at the closest location to your end user. We want to put every customer's code in every location, rather than forcing you to choose a handful. Meanwhile, obviously, not every one of our locations is a mega-datacenter.
This means we need a way to support extremely large numbers of tenants per machine, with relatively low traffic per tenant (because each tenant's traffic is spread out over the world). We need this to be efficient.
This means, we need low memory overhead (to support many tenants per machine), very fast cold-start time (since cold starts are a lot more common in a decentralized scenario), and low overhead to switch between workers (because we're mixing traffic from all our customers everywhere).
Using embedded V8 isolates within a single process gives us 10x-1000x better performance on all these metrics than if we gave a whole process to each customer.
Relatedly, here's a talk I gave at Heavybit about the neat things you can do when you have fine-grained server compute: https://www.youtube.com/watch?v=YZSvJNBZsxg
https://v8.dev/docs/untrusted-code-mitigations#sandbox-untru...
We've spent a lot of time thinking about and building mitigations for speculative side channel attacks. For example, early on in the project -- before anyone even knew about Spectre -- we made the decision that `Date.now()` would not advance during code execution, only when waiting for I/O. So, a tight loop that calls `Date.now()` repeatedly will keep getting the same value returned. We did this to mitigate timing side channels -- again, even though we didn't know about Spectre yet at the time.
Chrome has indeed stated that they believe process isolation is the only mitigation that will work for them. However, this statement is rather specific to the browser environment. The DOM API is gigantic, and it contains many different sources of non-determinism, including several explicit timers as well as concurrent operations (e.g. layout, rendering, etc.). Side channel attacks are necessarily dependent on non-determinism; a fully-deterministic environment essentially by definition has no covert side channels. But, there's no way Chrome can get there.
The Cloudflare Workers environment is very different. The only kinds of I/O available to a worker are HTTP in, HTTP out, `Date.now()`, and `crypto.getRandomValues()`. Everything else is perfectly deterministic.
So, for us, the problem is much narrower. We need to make sure those four inputs cannot effectively be leveraged into a side channel attack. This is still by no means trivial, but unlike in the browser, it's feasible. `getRandomValues()` is not useful to an attacker because it is completely non-deterministic. `Date.now()` we've already locked down as mentioned above. HTTP in/out can potentially be leveraged to provide external timers -- but the network is extremely noisy. A practical attack would require a lot of time in order to average out the noise -- enough time that we can do a bunch of higher-level things to detect and disrupt possible attacks. It helps that Workers are stateless, so we can reset a worker at any time and move it around, which makes attacks harder.
NetSpectre demonstrated that even physical network separation does not necessarily protect you against Spectre attacks. There's simply no such thing as a system that's perfectly secure against Spectre, process isolation or not. All we can do -- aside from going full BSG and giving up on networks altogether -- is make attacks harder to the point of infeasibility. Luckily, we have lots of tools in our toolbox for making Spectre attacks infeasible in the case of Cloudflare Workers.
2. "BSG"?
The Battlestar Galactica was the only ship in the fleet that hadn't networked its computers, because the captain was paranoid. When the Cylons (AI) attacked, they instantly hacked all the other ships, but the Galactica stayed under human control and got away.
It's fiction, but I'm honestly really impressed with this bit of writing. It's both an entirely plausible and almost realistic strategy, and it gives the writers an excuse for the crew members to interact rather than let the computer do everything. Whereas on Star Trek one wonders why they bother with a bridge crew -- the captain might as well be punching everything into a computer directly rather than inefficiently giving orders to humans.
I'm comforted by the fact that if there's a breakout in V8, Chrome is a much juicier target than we are -- and has an incredibly strong security team that will jump on the issue. I think we would be overall less secure using a lesser-known JS implementation.
1. No process isolation 2. Data from lots of users on any given node
Am I missing something?
* While process isolation makes Chrome somewhat less interesting than it used to be, keep in mind that process isolation is being rolled out as a defense to arbitrary-read attacks (like spectre), not arbitrary-code-execution attacks. Executed code can potentially talk to the rest of Chrome and perform actions that a web site is not intended to be allowed to. (At least in the past, this included the ability to read all the user's cookies, though it's possible they've improved on that, I don't know.)
* Cloudflare has potentially multiple tenants in a node, but the attacker has no control over who they are. There's no particularly good way to target a specific end user nor a specific web site.
* V8 vulnerabilities are likely to be memory safety issues, which are difficult to leverage into an attack without an understanding of the process's memory space, which is hard to get without having access to the source code or a compiled binary. The attacker would be flying blind and would almost certainly just segfault or be caught by our layer 2 sandbox (which blocks almost all syscalls), which incidentally would immediately alert us to their activity. (I don't particularly like this as a defense, since I like open source -- but frankly, it is a pretty big barrier.)
* The attacker would be burning their zero-day by uploading it to Cloudflare. We block eval() and the like, such that the only way to run code on our edge is by uploading it through our deployment APIs, which keep a copy.
* Last I checked, Chrome still does not use site isolation on mobile, because the overhead is too high.
If anything the industry is increasingly adopting bytecode as distribution format, kind of returning to the early 60/70's designs with microcoded CPUs just with another approach to the final execution.
The real benefit is having a portable bytecode that 1) can accommodate any language out there without constraining their object and memory model, and 2) is guaranteed to be compiled to native code by an optimizing compiler when deployed. Add some basic APIs, and we could have a situation that has heretofore has been enjoyed pretty much only by x86 - the ability to compile code, and run it 30 years later as is.
But C, C++, Rust, Go, D, etc... all support compilation to those platforms. This is a really common thing to do.
Almost inevitably JS will have the best interop, with the great trend for javascriptization of everything WASM could find it's way into all sorts of environments (like the native apps you mentioned).
People are already looking into WASM VMs for blockchains https://www.parity.io/wasm-smart-contract-development/
Now, I don't think it'll "take over" the way C has, but I also wouldn't be surprised to see it edging out other VMs in many contexts, like the Lua or Python VMs, which may end up porting to WebAssembly instead of trying to justify another dependency for your app.
I hope we'll finally get to the point where I can choose what language to use for a specific task based on the merits of the language instead of making the larger argument that it's worth getting it to work in our existing app.
[1] https://iodide.io/ [2] https://github.com/iodide-project/pyodide [3] https://iodide.io/iodide-examples/python.html
I've been watching efforts to port Lua to WebAssembly (the official VM looks simple enough, but luajit won't be easy) because I want to have an app that shares code with the browser, and it would be awesome to play with WebAssembly as the plugin system of choice on the backend.
I'm also super excited for nebulet[1], which is a micro-kernel experiment using WebAssembly in Ring 0, which is pretty neat.
I'm really excited to see where WebAssembly can go. I know many of these projects will peter out, but it's exciting nonetheless.
Absolutely. On the Lua front someone made a PoC to add Lua as a language for Iodide [1] using Fengari [2] which (while I haven't used it yet) definitely looks interesting. Hadn't heard of Nebulet before but will definitely be following it now. Cheers!
[1] https://groups.google.com/d/msg/iodide-dev/ahc4fg8_JLg/llkHS... [2] https://fengari.io/
Docker has won to a degree, though it still requires complex orchestration technologies like Kubernetes built on top of it, which are rapidly developing and not a particularly stable target.
> Although serverless and edge computing often use JavaScript.
Yes, this is where I see WASM really hold its own. Serverless and edge environments want to be able to have code running in a persistent process that is completely managed by the environment. Right now, they frequently offer just JS, or a couple of language runtime environments like Python as well; for serverless environments, you can generally load native modules if you want to, but its awkward, while edge environments will only run JS, though now they're starting to offer WASM.
It's the places where being able to run multiple tenants within a single process, without paying IPC and process isolation overheads, that make the overhead of WASM more likely to be worth it.
> On mobile this seems to depend on Apple and/or Google deciding to support WebAssembly for native apps, which seems unlikely.
I don't think it would be too unlikely for Google to support WASM for native apps. For one, it would allow them to do architecture independent apps without ART, on Fuchsia, for example. Right now, I think Dart + Flutter compiles to ARM code, but if they want to target a wider range of devices then platform independence could be important.
Not strictly true. I spent a bit of time using Cloud 9 and found it to be quite a useable experience. It’s certainly very handy to be able to access a dev environment from web browser wherever you happen to be.
I hear a lot of developers going on and on about laptops these days but I can't figure out why. Is working out of a coffee shop the norm now or something?
Well, unless you add Kubernetes on top of that... then yeah, it gets... complicated.
No.
I’m not a UXer, never was, and I moved into management long before programs even got pretty so I’ve never even had to pick up.
Yet I can make a pretty web application with vue with minimal efforts. Add stuff like graphql, and wasm looks so ridiculously old aged before it’s even born.
Of course that kind of defeatist attitude is silly, and I’m looking forward to see where wasm goes in the coming years, because if people just gave up, I wouldn’t have been able to make a pretty app in vue either.
Also, JS isn't the best tool for all programs, and programmers would like more of a choice when it comes to things that are more than just your standard web app.
Why not? Developing pretty apps in Vue (or anything in JS-land) is an horrible experience, why shouldn't we use WASM to port some better environment into there?
Presenting WASM as a threat will lead to it facing stiff resistance from entrenched interests (amazing that people in their 20s and 30s are entrenched interests, but that’s modern front-end development).
A more gradual, evolutionary, low-hype approach seems prudent, as the platform matures and until/if someone makes the “killer app”.
We used to work with, first WPF then web forms and later MVC with razor, and we very quickly bought Telerik because the standard UI components in .Net are horrible.
Aside from that I’ve worked with JAVA I can’t recall what we used before FX but both were terrible.
In the JS CSS environment I can literally make an interface that doesn’t look like ass by simply using the standard setup in a front end with very few lines of code.
I guess a think like Blazor.net might make wasm competitive, but unlike JS, that requires Microsoft not to drop it in a year because they don’t have the OS movement JS does.
I understand why people dislike the package he’ll of modern JS, but so far, it’s proven itself to be just as trustworthy as any curated library.
On the other hand you’re not tied down in JS. When Microsoft made entity they wanted people to use it, even though it’s fucking awful. In JS you can very easily replace a component if something better comes along. That’s a great strength.
Graphql has been really instrumental for us for instance. We operate apps in low connective environments, so being able to only transfer what is needed is really great.
Graphql isn’t JS only, but it takes very little time and effort to setup an Apollo, graphql and vue app, and it’s got very few issues. The .Net integration of graphql is still a 3rd party library that doesn’t really work that well and isn’t easy to use.
That’s the thing with JS, it’s just really productive in the real world.
Blazor.net looks really productive, but it’s only productive when you don’t need it to do something Microsoft hasn’t thought of, and it’s the only WASM integration that I’ve seen that is even remotely competitive with JS.
The largest problems of the web programming are lack of componentization and Javascript, we may be able to solve that last one soon!
The thing with JS is that it is a no batteries, no novelty, no shortcut, not very productive language, that manages to be both old-school and novel on all the bad ways. You can't just carelessly gather code and use it, because there are no safety boundaries; most code that is not at the frontend (yeah, like Apollo) have no consideration about security, so you can't simply expose it; the entire ecosystem is a house of cards; and the language itself is a pile of WTFs just waiting for you to discover another one.
Besides, the web stack is pretty much controlled by Google nowadays. Yes, they manage development resources better than Microsoft, but I would prefer working on a stable and free environment.
VS is great too, but it’s performance is really, really, terrible when your documents and settings directory is on one network drive and your codebase is on another. Not exactly VS’s fault, but it’s an ide for enterprise that can’t function with the most basic enterprise drive setup?
VSC, the electron app on the other hand doesn’t give two shits.
People usually tell me VSC is the one off unicorn. But isn’t discord better than team speak and ventrilo? Isn’t slack excellent?
I don’t think sunk cost is a negative when people are building better tools with it.
That said, even then, I'll take Qt over Electron any day of the week.
http://example.qt.io/qt-webassembly/quickcontrols2/gallery/g...
My reaction to using the canvas instead of the DOM is very, very, very negative by the way. Webpages with fake text that is actually pixels rendered to a canvas are currently mostly restricted to dystopian notions of either the end result of the ad-blocker arms race or else extreme anti-copying measures.
I'm certainly not using Xcode + Cocoa + the MVC abstraction for iOS/macOS apps because it's the superior way to build software. It has its own warts, like the effort it takes to swap out MVC with some other pattern, or how it comes with no async abstractions -- you'll just be writing callback code like JS developers had to before the Promise.
It's tempting to unmask "ugh, JS developers" as a bunch of idiots, but I think you'd only be kidding yourself if you think your pet environment is some global optimum.
Hell when we were still building interfaces in .Net we paid a subscription to use Telerik on the frontend because the standard .net stuff is absolutely terrible.
I never used Telerik, and we only bought ComponentOne once for a Windows Forms project, started before WPF even existed.
It's nuts that visual layout editors for the web have, if anything, regressed from the WebForms editor in Visual Studio 2008.
In any case you aren't obliged to use MVVM in WPF, it is just a best practice for easier unit testing and composability. Then again Web Components are only now starting to be a thing.
Some people will argue on this, but I'm actually in agreement.
That said, it is important to realize WHY the JS productivity is so important: We're iterating a LOT. Web is so young, web interfaces are so young, the problems we are trying to solve on web are ever changing, and the devices we use to interface with web are changing almost as fast. We have to iterate again and again to be decent at the problem we're trying to solve only to toss it aside in favor of the new problem.
Some of this is wasteful, some of this is just part of being part of a big technological change. (I'm sure TV, radio, fax, printers, copiers, etc all had similar iterations, albeit at not quite the same speeds). But regardless of the "if we should" aspect, it's important to note that the current JS needs are both (1) currently real - trying to adopt some philosophically "pure" tenet in the defiance of these needs will fail and (2) not necessarily permanent - We can extrapolate into the near future from this, but I'm hard pressed to say much about more than 2 years in the future.
> Add stuff like graphql
Funny, I thought about graphql when the article mentioned HTTP caches, since graphQL _can't_ make use of that (most graphQL implementations use non-GET for everything, so you have to rely on server-side or client-app caching, since you can't rely on the network or browser) and took it as a hit on graphQL, not wasm.
That said, I'm interested to see where wasm goes - short term, we're in agreement that anyone expecting it to be the "Js-killer" is missing the mark, but long term I don't expect it to be dead-on-arrival, just used for not-what-was-expected.
To me the main benefits of wasm are that you can * make web pages with languages besides JS * do lower level things not possible with JS (low latency real time games?)
If you already know JS well and want to make a normal website I don't think you need WASM necessarily although it will enable those who don't know JS or want to use JS to make them too.
So, it may not be completely intentional, but WASM does have roadmap items that may end up competing with JS. WASM starts to look more like a general purpose VM over time.
Stuff like UnrealEngine running in browser, low-latency audio processing, etc. Lots of potentially cool solutions where you need strong control over allocations and memory placement.
You don't need a jet engine to make paper airplanes. Gluing jet engines to paper airplanes would indeed be counterproductive.
> and wasm looks so ridiculously old aged before it’s even born.
Wasm is about achieving near native level performance. For libraries and such. Stuff that your pretty high level js frameworks might use.
On the server side, it seems like docker format has already won. Maybe cpu architecture portability doesn't matter there and x86 is good enough? Although serverless and edge computing often use JavaScript.
On mobile this seems to depend on Apple and/or Google deciding to support WebAssembly for native apps, which seems unlikely.
Developers need laptops to run their development environment in. I'm wondering if this might just be Linux tools running in a container on your laptop. Chromebooks seem to be moving in that direction.
The revival of something like Sandstorm might be interesting, but that's pretty speculative.