/examples/wasm/README.md
- Code: code.asyncmachine.dev
- Code: GitHub
This is a simple example of WASM interop and communication between two distributed async state machines
(foo and bar). The complete WASM support allows having a single state-machine which is fully (or selectively)
distributed across n servers and m browsers, using efficient diff-based synchronization.
Actors (server):
server-foomain state machine- RPC server (WS)
- aRPC client (WS / TCP)
rc-server-barnetwork mach
Actors (browser):
browser-barUI state machine- RPC server (WS / TCP over WS)
- aRPC client (WS)
rnm-browser-foonetwork machbrowser-foonet handler mach
Running
git clone https://github.com/pancsta/asyncmachine-go.gitcd asyncmachine-go/examples/wasmtask start
Implementation
net/rpc, cenkalti/rpc2, and coder/websocket
with TCP-over-WebSocket bridged using /tools/cmd/am-relay.
Debugging
Both server-foo and browser-bar connect to a single am-dbg instance running on
the server and can be stepped through, with context from all the other machines.
Both server-foo and browser-bar expose REPLs.

Interactively use the TUI debugger with data pre-generated by this example:
go run github.com/pancsta/asyncmachine-go/tools/cmd/am-dbg@latest \
--import-data https://assets.asyncmachine.dev/am-dbg-exports/wasm.gob.br \
mach://server-foo
Machine Diagrams
# render
am-vis --bird render-dump am-dbg-dump.gob.br
Extended Network Diagram
The extended machine diagram additionally contains RPC clients and servers (aka noise).
# generate with .env
AM_RPC_LOG_SERVER=1
AM_RPC_LOG_CLIENT=1
AM_RPC_LOG_MUX=1
AM_RPC_DBG=1
# render
am-vis --bird render-dump am-dbg-dump.gob.br
Click to expand the diagram
Commands
$ task --list-all
task: Available tasks for this project:
* build: Development build
* build-prod: Optimized build
* deps: List dependencies in deps.md
* deps-graph: Render dependencies graph in deps-graph.svg
* repl: Start REPL for both server and browser
* start: Build and start server
Further Work
The current implementation covers the server-browser network boundary being synchronized using aRPC, but WebWorkers
require additional bindings. This includes exposing ports, channels,
and ArrayBuffer as a
regular net/Conn. Because WebWorkers have access to WebSockets and fetch(), the main thread can be left to executing
UI changes only, while n workers (n == CPU cores - 1) will:
- process handlers for the same async state machine
- run a KV cache store
- run a DB via File System API
