Slide 1

Slide 1 text

1 WebAssembly for the backend Adrian Cole OSS Engineer

Slide 2

Slide 2 text

Open Source late bloomer Currently all-in on wazero.io and the people who use it 2 I’m Adrian from Tetrate codefromthecrypt on GitHub @adrianfcole

Slide 3

Slide 3 text

What does wasm do for me? 3 We have 30 minutes, let’s skip to the good stuff if you hear jargon you don’t know, only take note if you care its the context!

Slide 4

Slide 4 text

Service architecture WebAssembly as a way to modularize deeply embedded infrastructure 4

Slide 5

Slide 5 text

WebAssembly allows decoupling without RPC. Tools like go-plugin allow you to define ABI as protobuf services. 5 e.g. go-plugin gRPC Host Guest Decoupled with gRPC API Decoupled with WebAssembly Monolith Breaking the Monolith Service

Slide 6

Slide 6 text

Sidecar monoliths Sidecars are usually monolithic, and while highly customizable, tricky to change. For example, Envoy versions are tightly coupled to Istio versions. Dapr is a static binary, so cannot custom libraries dynamically. 6

Slide 7

Slide 7 text

Customizing sidecars with HTTP Middleware My App Middleware 1 Middleware 2 Middleware 3 Dapr Sidecar Request Response You install this You built this You configure this

Slide 8

Slide 8 text

You want to break the monolith My App Middleware 2 Middleware 3 Dapr Sidecar Request Response My Filter You can’t change this binary You built this You want to own this code

Slide 9

Slide 9 text

Sidecars define the WebAssembly function contract they support ABI is a contract between the host running wasm and the guest. It defines functions like an IDL. Dapr (golang) supports the http-wasm ABI, implementing the server side of an HttpHandler. Compatible middleware, compiled to wasm, can be replaced without changing Dapr 9

Slide 10

Slide 10 text

So.. WebAssembly can break the monolith My App Middleware 2 Middleware 3 Dapr Sidecar Request Response My Filter WebAssembly allows custom functionality in a static binary, based on an ABI contract http-wasm guest http-wasm host My Filter http-wasm/http-wasm-guest-tinygo v1.10

Slide 11

Slide 11 text

Container architecture WebAssembly plus WASI as a leaner container model 11

Slide 12

Slide 12 text

Containers images are platform specific Container images must be built for the intended OS + architecture. “FROM scratch” can reduce this to kernel+arch, but only for static binaries. Many applications require a base layer with dependencies like libc, complicating deployment 12

Slide 13

Slide 13 text

13 WebAssembly has no operating system ● Compiling to %.wasm removes platform dependencies ● You can compile it on linux and run it on windows ● wasm containers are emerging, but not mature

Slide 14

Slide 14 text

14 DIY WebAssembly containers work today if you mix abstractions Container integration means pushing a WebAssembly Virtual Machine into the container runtime. For example, wasmer or wasmtime in crun. Some goals of wasm containers is re- use of Dockerfile and OCI registries

Slide 15

Slide 15 text

Application architecture The most important thing about WebAssembly, is it is embeddable 15

Slide 16

Slide 16 text

16 ● Start a process (os/exec) ● Call a Foreign Function (CGO) Sometimes we want to call code we can’t import

Slide 17

Slide 17 text

Wasm cannot directly affect resources like files. Guests call imported host functions with pointers to shared memory they own. 17 out, err := run(ctx, fi leFS(path), "dcraw", "-e", "-c", "input") WASI commands are like os/exec but safer _start fd_read(input) args_get mem.Write(dcraw_-e_…) out.Write(mem) fi le.Read(mem) github.com/ncruces/RethinkRAW fd_write(stdout) memory dcraw.wasm wasi dcraw.c clang

Slide 18

Slide 18 text

Code may look similar, but wasm is very different than CGO 18 WebAssembly isn’t integrated like CGO, but it is safer. github.com/ncruces/go-sqlite3 Not C.CString Not unsafe.Pointer Dynamic not pre- defined in import “C”

Slide 19

Slide 19 text

19 So why bother with re-use with WebAssembly? github.com/ncruces/go-sqlite3 You can embed stateful processes into your application, provided they can be compiled to wasm and route I/O through WASI

Slide 20

Slide 20 text

Trivy provides an SDK which implements their custom ABI for config and analysis. Modules are installed locally or via OCI repository. 20 Wasm isn’t just for polygot, it can be a Go plugin implementation! trivy.dev acme-cves.wasm acme-cves.go Tinygo Trivy SDK ghcr.io/acme

Slide 21

Slide 21 text

There are a lot of difficulty still Especially backend WebAssembly is constrained and immature 21

Slide 22

Slide 22 text

Compilers are different or at least need different flags. Performance varies and is runtime specific. Benchmark! There are other ways to polyglot! 22 ● Features like reflection usually don’t work ● Wasm has no parallelism, so garbage collection is inline ● WebAssembly has no standard library, so binaries can get big. programming WebAssembly is trickier than normal code

Slide 23

Slide 23 text

What’s next for Go? (Normal) Go isn’t quite ready for backend WebAssembly 23

Slide 24

Slide 24 text

Go’s a little behind, but there’s hope The main go compiler has experimental GOARCH=wasm GOOS=js, so of limited use outside node.js and browsers. TinyGo works with WASI, but it lacks features like reflection. @johanbrandhorst proposed a GOOS=wasi compilation target which if accepted increases re-use 24 golang/go#58141

Slide 25

Slide 25 text

That’s all, folks! Let’s recap 25

Slide 26

Slide 26 text

Those interested can look at wazero.io or join #wazero on gophers slack! 26 ● WebAssembly impacts all layers of architecture, but it is an embedding solution ● Go developers can replace some os/exec and CGO patterns with wasm, as well make safe plugins. ● WebAssembly is tricky and evolving, so proceed with caution. Here are some good talks: Wasmer Things: An Upside Down Guide To WebAssembly by Edoardo Vacchi CGO-less Foreign Function Interface With WebAssembly by Takeshi Yoneda