microsoft / microsoft/duroxide
Improvements identified by PilotSwarm's session-lifecycle work: shutdown quiescence, session lock timeout exposure, JS abort cancellation, and more
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 217
- Forks
- 61
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 3
Description
PilotSwarm recently implemented a session lifecycle protocol on top of duroxide (atomic per-turn state commits, warm session-affinity holds, versioned CAS snapshots) and built a literal fault-injection harness that kills real worker processes at protocol boundaries and lets duroxide's retry machinery recover them. That work surfaced seven concrete improvement opportunities in duroxide core, duroxide-pg, and the Node binding — all verified against duroxide 0.1.29 / duroxide-pg 0.1.34 sources.
Full write-up with code references, impact analysis, and fix shapes:
https://github.com/affandar/PilotSwarm/blob/feature/session-lifecycle-protocol/docs/bugreports/duroxide-improvements-20260705.md
Summary, ranked by value-per-effort:
Runtime::shutdownshould return on quiescence, not sleep the full budget (runtime/mod.rs~1011). Dispatchers already quiesce early on the shutdown flag, but the call does an unconditionalsleep(timeout_ms)before aborting leftovers — every graceful drain pays its full budget in wall-clock. Fix:tokio::time::timeout(budget, join_all(joins))then abort, or a two-phasebegin_drain()/await_quiescence().- Expose the session lock timeout as a runtime option (duroxide-pg + node binding). The ~30s constant is the reclaim floor for session-pinned work after a worker crash — it dominates failover latency and makes kill/recovery test cycles ~30s slower each.
workerLockTimeoutMsis already exposed;sessionLockTimeoutMsshould mirror it. - Aborting an activity does not cancel its JS execution (duroxide-node).
JoinHandle::abort()orphans the JS promise; the activity body keeps running on the Node event loop after shutdown returns. Propagate cancellation (e.g. an AbortSignal in the activity context) or document + provide an await-settlement API. - Quiescence observability:
JsMetricsSnapshothas cumulative counters but no in-flight gauge, and the shutdown flag can't be set without committing to the fused blocking call. - Document/test the retry-with-same-input contract: work-item retries re-deliver byte-identical input — application-level idempotency schemes hang off this; it deserves to be a stated guarantee. Nicety: expose the delivery attempt number in the activity context.
- Surface session lease lifecycle events (claimed/renewed/idle-expired/reclaimed) — affinity loss is currently silent to the host.
- (Design discussion) Optional session epochs — a lease-transfer epoch stamped on work items would give stateful-session applications the zombie-duplicate fence they currently must build themselves.
Happy to split these into individual issues and/or send PRs for 1–2, which are small and isolated.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked write-up, then read runtime/mod.rs around line 1011 and the referenced duroxide-pg and Node binding code. Use the fault-injection harness to validate one narrowly scoped improvement; done means its behavior is tested or documented, rather than attempting all seven proposals together.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js, rust
- Domain
- backend, distributed-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100