59 lines
3.2 KiB
Markdown
59 lines
3.2 KiB
Markdown
|
|
# Constraints — In-Browser Swactor Runtime
|
||
|
|
|
||
|
|
## Threading Model
|
||
|
|
|
||
|
|
- **wasm-threads is mandatory** — the runtime uses SharedArrayBuffer + WebAssembly atomics for multi-worker parallelism. There is no single-threaded degraded mode for MVP.
|
||
|
|
- Browsers must serve pages with COOP/COEP headers:
|
||
|
|
- `Cross-Origin-Opener-Policy: same-origin`
|
||
|
|
- `Cross-Origin-Embedder-Policy: require-corp`
|
||
|
|
- Build requires nightly Rust + `-Z build-std=std,panic_abort` + target features `+atomics,+bulk-memory,+mutable-globals`.
|
||
|
|
|
||
|
|
## Architecture Rules
|
||
|
|
|
||
|
|
- **Platform abstractions live in core swactor** (`src/`), gated by `#[cfg(target_arch = "wasm32")]`. They do not belong in the wasm crate.
|
||
|
|
- **Do not add new modules** to `src/` — modify existing files only (TASK.md style rule).
|
||
|
|
- **Do not restructure** existing module boundaries. The abstraction is a thin layer (type aliases, cfg-gated imports), not a trait-based HAL.
|
||
|
|
- The browser crate (`crates/wasm-browser/` or evolved `crates/wasm/`) is a **thin wasm-bindgen shell**. All scheduling, routing, and actor logic stays in core Rust.
|
||
|
|
|
||
|
|
## Actor Model
|
||
|
|
|
||
|
|
- **Rust-only actors** — actors are written in Rust and compiled to wasm. JavaScript does not define actor behavior.
|
||
|
|
- JS interacts through the wasm-bindgen API: create runtime, spawn actors (by registered type), send messages, receive results.
|
||
|
|
- Actor types are registered at compile time via Rust generics, not dynamically from JS.
|
||
|
|
|
||
|
|
## Performance Priorities
|
||
|
|
|
||
|
|
- Maximize throughput: auto-scheduling via `setTimeout(0)` tight loop, not `requestAnimationFrame` (which caps at display refresh rate).
|
||
|
|
- Web Worker count defaults to `navigator.hardwareConcurrency` for full core utilization.
|
||
|
|
- Zero-copy where possible: SharedArrayBuffer eliminates serialization between workers.
|
||
|
|
- Minimize JS↔Wasm boundary crossings — batch operations where feasible.
|
||
|
|
|
||
|
|
## Feature Scope
|
||
|
|
|
||
|
|
- All core features that compile for wasm32: spawn, send, receive, tick, actor lifecycle, watching, extensions.
|
||
|
|
- swactor-std features (naming, groups, monitoring) should work if they compile.
|
||
|
|
- Transport: WebSocket adapter for distributed clusters. STUN/TURN (WebRTC) deferred to later.
|
||
|
|
- Features that require OS primitives not available in wasm (filesystem, raw TCP) are excluded.
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
- Tests must pass on both native (`cargo test`) and wasm targets.
|
||
|
|
- Wasm tests use `wasm-pack test --headless --chrome` or Node.js with `--experimental-wasm-threads`.
|
||
|
|
- No test-only code paths that diverge native vs wasm behavior — if it works differently, it's a bug.
|
||
|
|
- Prefer scenario tests over structural tests (per project testing rules).
|
||
|
|
|
||
|
|
## Dependencies
|
||
|
|
|
||
|
|
- `web-time` — drop-in replacement for `std::time::Instant` on wasm32
|
||
|
|
- `wasm-bindgen` + `js-sys` + `web-sys` — browser API bindings (in the wasm crate only, not core)
|
||
|
|
- `gloo-timers` — optional, for ergonomic setTimeout/setInterval
|
||
|
|
- No new dependencies in core swactor beyond `web-time` (which is no-op on native)
|
||
|
|
|
||
|
|
## What We Don't Do
|
||
|
|
|
||
|
|
- No async/await runtime (tokio, async-std) — swactor is synchronous tick-based
|
||
|
|
- No Emscripten — target is `wasm32-unknown-unknown` only
|
||
|
|
- No WASI — browser environment, not server-side wasm
|
||
|
|
- No JS actor definitions — Rust only
|
||
|
|
- No polyfills for missing atomics — if SharedArrayBuffer isn't available, the runtime doesn't start
|