Documentation
¶
Overview ¶
Snapshot artifact layout and validation per plans/wasm-runtime.md §4.8.1.
Index ¶
- Constants
- Variables
- func DirExists(dir string) bool
- func EngineNameWasmtime() string
- func EngineNameWazero() string
- func FenceCloneGeneration(rowGen, snapshotGen string) error
- func ListenerFD(caps Capabilities) int
- func MemoryLimitPages(memoryMB int) uint32
- func ResolvedListenPort(mod api.Module) (port int, ok bool)
- func SnapshotMediaTypes() map[string]string
- func WallTimeoutFromCaps(caps Capabilities) time.Duration
- func WithInvocationDeadline(ctx context.Context, caps Capabilities) (context.Context, context.CancelFunc)
- func WriteSnapshotDir(dst string, cap SnapshotCapture) error
- type ByteMeter
- type Capabilities
- type Engine
- type LoadOptions
- type LoadTimingReporter
- type LoadTimings
- type MultiInstanceEngine
- func (m *MultiInstanceEngine) ClearNetworkHook(sandboxID string)
- func (m *MultiInstanceEngine) Close(ctx context.Context) error
- func (m *MultiInstanceEngine) HasInstance(sandboxID string) bool
- func (m *MultiInstanceEngine) InstanceCount() int
- func (m *MultiInstanceEngine) Instantiate(ctx context.Context, sandboxID string, caps Capabilities) error
- func (m *MultiInstanceEngine) InvokeExport(ctx context.Context, sandboxID, name string) error
- func (m *MultiInstanceEngine) LastLoadTimings() LoadTimings
- func (m *MultiInstanceEngine) LoadModule(ctx context.Context, path string) error
- func (m *MultiInstanceEngine) Loaded() bool
- func (m *MultiInstanceEngine) MemoryMB() int
- func (m *MultiInstanceEngine) Run(ctx context.Context, sandboxID string, caps Capabilities, export string) (RunResult, error)
- func (m *MultiInstanceEngine) SetNetworkHook(sandboxID string, hook *NetworkHook)
- func (m *MultiInstanceEngine) StopInstance(ctx context.Context, sandboxID string) error
- type NetByteCounter
- type NetDialer
- type NetworkAwareEngine
- type NetworkHook
- type Preopen
- type RunResult
- type SnapshotBaseModule
- type SnapshotCapture
- type SnapshotConfig
- type SnapshotRestoreInput
- type UsageStats
Constants ¶
const DefaultWallTimeout = 5 * time.Minute
DefaultWallTimeout is the invocation budget when Capabilities.WallTimeoutNs is zero.
const ListenFDEnv = "AEROL_WASM_LISTEN_FD"
ListenFDEnv carries the wasip1 listener fd to AerolVM-aware guests. Guests that hardcode fd 3 (the bare-wasip1 convention) keep working when no dir preopens are configured; guests that also need /work read this env var to find the listener.
const WASIListenPortDisabled = -1
WASIListenPortDisabled means no wasip1 TCP listener is pre-opened (default).
Variables ¶
var ErrEmptySnapshotDir = errors.New("snapshot directory missing")
ErrEmptySnapshotDir is returned when a checkpoint path is missing on disk.
var ErrNetworkEgressBlocked = errors.New("network egress blocked by quota")
ErrNetworkEgressBlocked is returned when quota policy blocks outbound dials.
Functions ¶
func EngineNameWasmtime ¶
func EngineNameWasmtime() string
EngineNameWasmtime returns the §4.8.1 engine identifier for the optional wasmtime backend (UC-42b).
func EngineNameWazero ¶
func EngineNameWazero() string
EngineNameWazero returns the §4.8.1 engine identifier for the default backend.
func FenceCloneGeneration ¶
FenceCloneGeneration rejects snapshots older than the store row token.
func ListenerFD ¶
func ListenerFD(caps Capabilities) int
ListenerFD returns the fd wazero assigns the single wasip1 TCP listener: stdio (0–2), then len(preopens) dir fds, then the listener (InitFSContext order).
func MemoryLimitPages ¶
MemoryLimitPages converts a MiB cap to WASM pages (64KiB each). Zero means no limit.
func ResolvedListenPort ¶
ResolvedListenPort returns the host TCP port bound by a wasip1 pre-open listener.
func SnapshotMediaTypes ¶
SnapshotMediaTypes documents the v1 layer media types for AOCR push.
func WallTimeoutFromCaps ¶
func WallTimeoutFromCaps(caps Capabilities) time.Duration
WallTimeoutFromCaps returns the wall-clock budget for one guest invocation.
func WithInvocationDeadline ¶
func WithInvocationDeadline(ctx context.Context, caps Capabilities) (context.Context, context.CancelFunc)
WithInvocationDeadline wraps ctx with the caps wall timeout (epoch-style on wazero).
func WriteSnapshotDir ¶
func WriteSnapshotDir(dst string, cap SnapshotCapture) error
WriteSnapshotDir atomically writes a mem.snap directory at dst.
Types ¶
type Capabilities ¶
type Capabilities struct {
Env map[string]string `json:"env,omitempty"`
Preopens []Preopen `json:"preopens,omitempty"`
Args []string `json:"args,omitempty"`
MemoryMB int `json:"memory_mb,omitempty"`
WallTimeoutNs int64 `json:"wall_timeout_ns,omitempty"`
// WASIListenPort enables wasip1 pre-open TCP listeners when >= 0 (0 = ephemeral).
// When unset, use -1 to disable.
WASIListenPort int `json:"wasi_listen_port,omitempty"`
WASIListenHost string `json:"wasi_listen_host,omitempty"`
}
Capabilities configures WASI preopens, env, args, and resource limits for an instance.
func CapsFromResourceLimits ¶
func CapsFromResourceLimits(base Capabilities, memoryMB int, wallTimeout time.Duration) Capabilities
CapsFromResourceLimits projects host limits into engine capabilities.
func (Capabilities) ListenEnabled ¶
func (c Capabilities) ListenEnabled() bool
ListenEnabled reports whether wasip1 pre-open TCP listeners are active.
type Engine ¶
type Engine interface {
// LoadModule compiles bytes from path. Idempotent per path within one engine.
LoadModule(ctx context.Context, path string, opts LoadOptions) error
// Instantiate creates a runnable instance with the given capabilities.
Instantiate(ctx context.Context, caps Capabilities) error
// InvokeExport calls an exported function by name.
InvokeExport(ctx context.Context, name string) error
// Run re-instantiates with caps, invokes export, and captures stdout/stderr.
Run(ctx context.Context, caps Capabilities, export string) (RunResult, error)
// StopInstance tears down the active instance but keeps the compiled module.
StopInstance(ctx context.Context) error
// CaptureSnapshot exports linear memory from the active instance.
CaptureSnapshot(ctx context.Context) (SnapshotCapture, error)
// RestoreSnapshot re-instantiates and loads memory from a capture.
RestoreSnapshot(ctx context.Context, snap SnapshotRestoreInput, caps Capabilities) error
// Close releases compiled module and any active instance.
Close(ctx context.Context) error
// ResolvedListenPort returns the host port for an ephemeral wasip1 listener (0 in caps).
ResolvedListenPort() (int, bool)
// SupportsListen reports whether the engine can host a wasip1 TCP listener
// (the HTTP ingress / expose_port path). wazero can; the wasmtime backend
// cannot yet (see plans/wasm-runtime.md "Still open"). Callers must reject
// listen requests up front rather than silently failing to resolve a port.
SupportsListen() bool
}
Engine compiles and runs a single WASM module with WASI.
type LoadOptions ¶
type LoadOptions struct {
MemoryMB int
}
LoadOptions carries per-load engine configuration. MemoryMB sets the wazero runtime memory-limit pages before compilation so a later Instantiate with the same cap does not rebuild the runtime (plans/wasm-create-latency.md Phase 1).
type LoadTimingReporter ¶
type LoadTimingReporter interface {
LastLoadTimings() LoadTimings
}
LoadTimingReporter is an optional engine capability: an engine that implements it exposes the sub-stage breakdown of its most recent LoadModule. It is type-asserted by the worker (like NetworkAwareEngine) so the base Engine interface — and the wasmtime backend and the test mocks that implement it — stay untouched.
type LoadTimings ¶
type LoadTimings struct {
NewEngine time.Duration `json:"new_engine_ns,omitempty"`
RuntimeInit time.Duration `json:"runtime_init_ns,omitempty"`
Read time.Duration `json:"read_ns,omitempty"`
Compile time.Duration `json:"compile_ns,omitempty"`
}
LoadTimings breaks the cold-create wasm_load stage into its sub-costs. It exists because a single wasm_load timer told us the stage was ~2.8s p50 for CPython on t3.medium but not WHICH step owned it — and the firecracker create-latency episode proved that guessing the dominant sub-cost before measuring it burns effort on the wrong lever. Splitting the timer lets the create path emit per-step Server-Timing entries so the resident-module work (plans/wasm-resident-module-host.md) targets the real bottleneck.
The fields mirror the cold LoadModule sequence in the worker:
NewEngine — worker: NewEngineFor builds the first wazero runtime + WASI.
RuntimeInit — engine: LoadModule rebuilds the runtime at the target memory
limit (+ WASI + compile-cache open). This is a second runtime
build today; see the plan's "redundant double init" note.
Read — engine: os.ReadFile of the module bytes (25MB for CPython).
Compile — engine: wazero CompileModule (compile-cache assisted; a full
cold compile is ~10s, a cache hit ~seconds of deserialize).
Durations marshal to JSON as their nanosecond integer (time.Duration is int64), so they cross the worker IPC boundary losslessly.
type MultiInstanceEngine ¶
type MultiInstanceEngine struct {
// contains filtered or unexported fields
}
MultiInstanceEngine holds one resident wazero runtime + one compiled module and instantiates many isolated instances from it — compile-once, instantiate-many. It is the Phase 1 primitive for the resident-module host (plans/wasm-resident-module-host.md), extended in Phase 2b PR-A with per-instance network hooks (multiNetHost) and call/lifecycle locking.
Bucketing constraint: wazero sets the memory limit at the runtime level and a CompiledModule is bound to its runtime, so one MultiInstanceEngine serves a single (module, memoryMB) bucket. MemoryMB is fixed at construction.
Isolation: wazero gives every InstantiateModule its own linear memory. Networking is keyed by mod.Name() (= sandboxID) via multiNetHost so co-tenants cannot share sockets. wasip1 listeners and checkpoint/restore remain out of scope for resident hosts.
func NewMultiInstanceEngine ¶
func NewMultiInstanceEngine(ctx context.Context, memoryMB int) (*MultiInstanceEngine, error)
NewMultiInstanceEngine builds the resident runtime (memory-limited to memoryMB, sharing the on-disk compile cache + base wasip1 host) with no module compiled yet. Call LoadModule once, then Instantiate per sandbox.
func (*MultiInstanceEngine) ClearNetworkHook ¶
func (m *MultiInstanceEngine) ClearNetworkHook(sandboxID string)
ClearNetworkHook drops the sandbox's hook and closes every conn it owns.
func (*MultiInstanceEngine) Close ¶
func (m *MultiInstanceEngine) Close(ctx context.Context) error
Close tears down every instance, the compiled module, and the runtime.
func (*MultiInstanceEngine) HasInstance ¶
func (m *MultiInstanceEngine) HasInstance(sandboxID string) bool
HasInstance reports whether sandboxID has a live instance.
func (*MultiInstanceEngine) InstanceCount ¶
func (m *MultiInstanceEngine) InstanceCount() int
InstanceCount is the number of live instances (for pool accounting + tests).
func (*MultiInstanceEngine) Instantiate ¶
func (m *MultiInstanceEngine) Instantiate(ctx context.Context, sandboxID string, caps Capabilities) error
Instantiate creates an isolated instance keyed by sandboxID from the resident compiled module. This is the fast path the whole design exists for: it costs an Instantiate (~9ms), not a CompileModule (~2.8s). _start is NOT run here (deferred, matching the single-instance engine); callers invoke it explicitly.
func (*MultiInstanceEngine) InvokeExport ¶
func (m *MultiInstanceEngine) InvokeExport(ctx context.Context, sandboxID, name string) error
InvokeExport calls an exported function on one instance. The engine lock is released before the call so a long-running export does not serialize co-tenants; the per-instance lock keeps StopInstance from Closing underfoot.
func (*MultiInstanceEngine) LastLoadTimings ¶
func (m *MultiInstanceEngine) LastLoadTimings() LoadTimings
LastLoadTimings satisfies LoadTimingReporter. NewEngine/RuntimeInit are left zero — this engine builds its runtime once at construction, not per load.
func (*MultiInstanceEngine) LoadModule ¶
func (m *MultiInstanceEngine) LoadModule(ctx context.Context, path string) error
LoadModule compiles the module at path once; every later Instantiate reuses the resident CompiledModule. A repeat call recompiles (e.g. module upgrade) and closes the previous compiled module — existing live instances keep running on their own already-instantiated code.
func (*MultiInstanceEngine) Loaded ¶
func (m *MultiInstanceEngine) Loaded() bool
Loaded reports whether a module has been compiled into the resident runtime.
func (*MultiInstanceEngine) MemoryMB ¶
func (m *MultiInstanceEngine) MemoryMB() int
MemoryMB is the fixed memory limit (MB) this engine's runtime + compiled module are built for. The pool routes only matching-memory creates here.
func (*MultiInstanceEngine) Run ¶
func (m *MultiInstanceEngine) Run(ctx context.Context, sandboxID string, caps Capabilities, export string) (RunResult, error)
Run (re-)instantiates the sandbox's instance with stdout/stderr capture and invokes export (default _start), returning the captured output — the one-shot Exec path for a resident-hosted sandbox. It mirrors the single-instance engine's Run (re-instantiate per call so a fresh Exec starts clean), but keyed by sandboxID and reusing the resident compiled module, so it costs an Instantiate (~9ms), not a compile. A non-zero guest exit is returned in the RunResult (not as a Go error), matching the single-instance engine.
func (*MultiInstanceEngine) SetNetworkHook ¶
func (m *MultiInstanceEngine) SetNetworkHook(sandboxID string, hook *NetworkHook)
SetNetworkHook binds a per-sandbox NetworkHook for mediated egress. The hook is looked up at host-fn call time by mod.Name() (= sandboxID).
func (*MultiInstanceEngine) StopInstance ¶
func (m *MultiInstanceEngine) StopInstance(ctx context.Context, sandboxID string) error
StopInstance closes one instance and leaves every co-tenant running. Idempotent: stopping an unknown sandboxID is a no-op. Waits for in-flight InvokeExport/Run calls on that instance, then closes owned network conns.
type NetByteCounter ¶
type NetByteCounter struct {
// contains filtered or unexported fields
}
NetByteCounter is a thread-safe ByteMeter backed by atomic counters.
func (*NetByteCounter) AddIn ¶
func (c *NetByteCounter) AddIn(n int64)
func (*NetByteCounter) AddOut ¶
func (c *NetByteCounter) AddOut(n int64)
func (*NetByteCounter) In ¶
func (c *NetByteCounter) In() int64
func (*NetByteCounter) Out ¶
func (c *NetByteCounter) Out() int64
type NetDialer ¶
type NetDialer interface {
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
NetDialer dials outbound TCP for a sandbox. Implementations must enforce egress policy and byte accounting (UC-43 NetMediator in the worker).
type NetworkAwareEngine ¶
type NetworkAwareEngine interface {
Engine
SetNetworkHook(hook *NetworkHook)
ClearNetworkHook()
}
NetworkAwareEngine exposes per-sandbox network mediation on the default engine.
type NetworkHook ¶
type NetworkHook struct {
SandboxID string
Dial NetDialer
// Meter receives wasip1 sock_accept/recv/send and host-module socket bytes.
Meter ByteMeter
}
NetworkHook binds a sandbox identity to mediated egress dials for the engine.
type RunResult ¶
type RunResult struct {
ExitCode int `json:"exit_code"`
Stdout string `json:"stdout,omitempty"`
Stderr string `json:"stderr,omitempty"`
Usage UsageStats `json:"usage,omitempty"`
}
RunResult captures a single invocation's outcome.
type SnapshotBaseModule ¶
SnapshotBaseModule references the compiled module by digest.
type SnapshotCapture ¶
type SnapshotCapture struct {
Config SnapshotConfig
Memory []byte
Globals []byte
WASIState []byte
}
SnapshotCapture holds the host-boundary state written into mem.snap.
type SnapshotConfig ¶
type SnapshotConfig struct {
SchemaVersion int `json:"schema_version"`
Engine string `json:"engine"`
EngineVersion string `json:"engine_version"`
WASIVersion string `json:"wasi_version"`
BaseModule SnapshotBaseModule `json:"base_module"`
Entrypoint string `json:"entrypoint"`
Durability string `json:"durability"`
CapturedAt string `json:"captured_at"`
CloneGeneration string `json:"clone_generation"`
MemoryChecksum string `json:"memory_checksum"`
WASIStateChecksum string `json:"wasi_state_checksum"`
GlobalsCount int `json:"globals_count"`
}
SnapshotConfig is the v1 config descriptor (§4.8.1).
type SnapshotRestoreInput ¶
type SnapshotRestoreInput struct {
Config SnapshotConfig
Memory []byte
Globals []byte
WASIState []byte
}
SnapshotRestoreInput is validated artifact content for engine reconstruction.
func ReadSnapshotDir ¶
func ReadSnapshotDir(dir string, runningEngine string) (SnapshotRestoreInput, error)
ReadSnapshotDir loads and validates a mem.snap directory.
type UsageStats ¶
type UsageStats struct {
WallDurationMs int64 `json:"wall_duration_ms"`
// Instructions is populated only on the wasmtime engine seam (UC-42b).
Instructions int64 `json:"instructions,omitempty"`
}
UsageStats captures per-invocation metering for billing (UC-42a on wazero).