refactor(runtime): generic frame-context resolver registry#422
Closed
wolfy-j wants to merge 5 commits into
Closed
Conversation
Frame-decorating options (the network overlay, and future ones like a filesystem root) were hand-wired into every dispatcher: the process manager and both the wasm and lua function lifecycles each called netapi.ApplyOverlayPair, leaking api/net into generic machinery and forcing every new option to touch every dispatcher. Introduce ctxapi.FrameResolvers: an ordered registry of (ctx, options) -> ([]Pair, error) resolvers, carried on the AppContext and populated once at boot. The two real choke points — the function registry executor (shared by lua and wasm) and the process manager Start — apply the whole set generically. Reads are lock-free (atomic snapshot, copy-on-write on register), mirroring the interceptor registry; the no-resolver path is ~1.4ns with zero allocations. Network migrates onto it: api/net.OverlayResolver replaces ApplyOverlayPair and is registered by the network boot component. The dispatchers no longer import api/net or api/fs; a new frame-context option is one resolver plus one Register line, with no dispatcher edits.
- Keep api/net.ApplyOverlayPair as a deprecated thin wrapper over OverlayResolver so out-of-tree Go callers do not break (codex). - Network boot component fails loud (ErrFrameResolversMissing) instead of silently skipping registration when the registry is absent, so a wiring bug cannot degrade the overlay to clearnet (fable #1). - Remove the now-redundant SetMultiple(task.Context) from the wasm and lua Execute handlers: the function registry executor already applies task.Context to the same forked frame and is the sole caller (fable #3). - Drop the speculative FrameResolverOrderFSRoot constant and fs-root comment references; this PR migrates only the network overlay (fable #4). - Fix stale comments and the test section header (fable #5).
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Options that decorate a newly-spawned frame's context (today: the network overlay; soon: a filesystem
fs_root) were hand-wired into every dispatcher —system/process/manager.goStart()and bothruntime/{wasm,lua}/component/function/lifecycle.goExecute()each callednetapi.ApplyOverlayPair. That leaksapi/net(and would leakapi/fs,api/service/otel, ...) into generic machinery, and every new frame option must be added to every dispatcher.What
ctxapi.FrameResolvers— an ordered registry of resolvers:Carried on the AppContext (like the interceptor registry), populated once at boot. The two real choke points apply the whole set generically:
system/function/functions.goexecutor()— shared by lua and wasm functions.system/process/manager.goStart().Adding a frame-context option is now one resolver + one
Registerline, zero dispatcher edits. The dispatchers no longer importapi/net/api/fs.Network migrated
api/net.OverlayResolver()replacesApplyOverlayPair(same logic: per-call → app-default precedence,ErrNetworkNotFoundfor unknown ids) and is registered by the network boot component (order 200). Thenetapicalls + imports are removed from all three dispatchers.Performance
Reads are lock-free — an atomic snapshot pointer (copy-on-write under a mutex only in
Register), mirroring the interceptor registry'schain.Load(). Benchmarks:Race-tested (
go test -race).Not in this PR
fs_rootregisters its resolver on this mechanism (that PR builds on this one).Tests
api/context: registry order, append-to-input, nil-receiver no-op, first-error-stops-and-wraps (errors.Ispreserved), duplicate/nil rejection, ctx round-trip, benchmarks.api/net:ApplyOverlayPairtests retargeted toOverlayResolver.system/process: manager network tests now wire the resolver registry, proving the manager applies it generically.