feat(runtime): deferred-dispatch admission bound per ADR 0015 - #56
Conversation
…ached / MaxDetachedPerTenant) Closes #44
|
@codex review |
|
@codex security review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5199976541
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
@codex review |
|
@codex security review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
Implements the deferred-dispatch Admission Bound decided by ADR 0015 (merged in 984d094). Closes #44.
Runtime
RuntimeOptions.MaxDetached— per-instance cap on admitted-but-incomplete deferred dispatches. Required positive underDispatchDeferred(constructor validation, theDetachTimeoutprecedent);DefaultRuntimeOptions()sets 1024; sizing guidance lives on the option's GoDoc. Everything a delivery retains counts: running tails, parked queue/debounce waiters, concurrent slot-waiters — and capacity frees only when the tail goroutine returns, so stalled cleanup still counts as retention.RuntimeOptions.MaxDetachedPerTenant(0 = disabled) — a per-installation ceiling keyed on ADR 0006's(adapter, tenant)identity, through the same rejection path (a ceiling, not a reservation). Per-tenant counters are garbage collected at zero. An empty tenant is a countable key, not an escape.ErrAdmissionRejectedbefore any State work — the delivery is never marked in Event Identity, so the platform's retry is not deduped away (the ADR 0002/0003 qualification recorded in ADR 0015 §1).Shutdownis rejected with the same signal instead of being admitted into a runtime about to cancel its work.admission_rejectedobservation (adapter + tenant attrs) andadmission-rejectedterminal dispatch outcome.Shape-aware adapter mappings (ADR 0015 §1)
Hardening tests — the five named failure modes from the #54 review history
TestAdmissionSlotReleasedOnErroredAndResolvedPreludes(erroredAcquireLockpreludes and synchronously-resolved ignored events all return capacity).TestAdmissionSlotHeldUntilTailGoroutineReturns(handler returned,ReleaseLockstalled → slot still held; frees when the goroutine returns).TestAdmissionClosedOnShutdown.TestAdmissionOptionValidation(MaxDetached <= 0andMaxDetachedPerTenant < 0rejected under deferred; ignored under sync) +TestAdmissionPerTenantCeilingKeysOnInstallation(empty tenant is a countable installation key).TestAdmissionPerTenantCounterGC(entries exact while in flight, zero after release; via a test-only accessor).Plus:
TestAdmissionRejectsAtMaxDetachedWithoutDedupeMark(sentinel surfaced, observation/outcome emitted, rejected Event Identity handled normally once capacity frees), per-strategy retention pins for queue waiters and concurrent slot-waiters, and adapter mapping tests for all four shapes (Slack ×3, Linear end-to-end through a saturated deferred runtime).Docs (in scope per the issue contract)
MaxDetachedbullet; runtime GoDoc comments updated where ADR 0015 superseded ADR 0012 phrasing; hello-world example setsMaxDetached.Additive API only; no new dependencies. Note: deferred configurations built without
DefaultRuntimeOptions()must now setMaxDetached— deliberate per ADR 0015 ("no unbounded production default survives this ADR").Validation
mise run vet— clean across all workspace modules.GOFLAGS=-race mise run test— all modules ok (root, adapters, examples, state/memory, state/nats, state/postgres, state/redis).Generated with
mux• Model:anthropic:claude-fable-5• Thinking:xhigh