Rename Durable Object rollouts to worker session policies - #11
Conversation
Rename the contract to sessionPolicy across Control, Gateway, do-runtime, Workflows, and the shared JS/Rust fixtures — the deploy field, promote response, worker:session-policy Redis keys, and the session-policy:restart channel — dual-reading only the retired durableObjectRollout bundle-meta field persisted by earlier releases and rejecting it in deploy requests. Drop the Durable Object binding requirement so any worker, including pure WebSocket workers, may opt into restart: open public WebSockets close with 1012 at promotion, stale facets abort on their next dispatch, and new requests reach the promoted version under either policy. Keep promote-time doStorageId validation fail-closed, move worker-level policy documentation from the Durable Objects module doc to control-auth and gateway, and widen the upgrade note to pause Control mutations across the whole reader-then-writer roll. Signed-off-by: Lu Zhang <lu@wdl.dev>
There was a problem hiding this comment.
Pull request overview
This PR updates WDL’s worker lifecycle “restart vs preserve” control by renaming the former Durable Object rollout concept (durableObjectRollout) to a worker-level session policy (sessionPolicy), migrating the persisted Redis keys/channels accordingly, and broadening sessionPolicy: "restart" to apply to pure WebSocket workers (not requiring a DO binding). It also restores promote-time doStorageId fail-closed validation and refreshes cross-language contracts, fixtures, tests, and docs to match the new naming and semantics.
Changes:
- Renamed
durableObjectRollout→sessionPolicyacross Control API payloads, shared JS/Rust contract helpers, Redis keys (worker:session-policy:*,worker:session-policy-seq:*), and the restart pub/sub channel (session-policy:restart), with dual-read of retired bundle metadata. - Allowed
sessionPolicy: "restart"without requiring a Durable Object binding, enabling promote-time1012disconnect behavior for pure WebSocket workers. - Restored/strengthened promote-time validation for DO bindings’
doStorageIdcoherence and updated tests/docs to reflect the updated contract.
Reviewed changes
Copilot reviewed 48 out of 49 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/worker-contract.test.js | Updates unit coverage for session policy keys/channels and projection/event codecs. |
| tests/unit/style-contracts.test.js | Enforces new Redis key helper usage for worker:session-policy:* literals. |
| tests/unit/gateway-websocket.test.js | Renames WebSocket lifecycle tests to match session policy terminology. |
| tests/unit/gateway-runtime.test.js | Updates gateway subscriber/lifecycle snapshot tests for new channel/key names. |
| tests/unit/gateway-index.test.js | Renames test harness fields and lifecycle snapshot plumbing to “policy”. |
| tests/unit/do-runtime-protocol.test.js | Updates DO invoke normalization expectations to sessionPolicy. |
| tests/unit/do-runtime-actor.test.js | Renames session restart behavior and observability event identifiers. |
| tests/unit/do-owner-registry.test.js | Updates owner-registry fencing options and projection reads to session policy. |
| tests/unit/control-secret-envelope-handlers.test.js | Updates expectations for Redis keys touched during secret mutation. |
| tests/unit/control-routing.test.js | Adds/updates tests for dual-read precedence, invalid meta, and restart-without-DO behavior. |
| tests/unit/control-promote-handler.test.js | Ensures promote responses expose sessionPolicy rather than the retired field. |
| tests/unit/control-deploy-watch.test.js | Updates deploy behavior tests for new request field and restart-without-DO acceptance. |
| tests/unit/control-delete-handler.test.js | Updates delete flows to remove session policy projections while retaining allocators. |
| tests/integration/gateway-websocket.test.js | Adds integration coverage for restart policy disconnecting pure WebSocket workers on promote. |
| tests/integration/durable-objects-websocket.test.js | Renames DO WebSocket restart tests and updates deploy metadata to sessionPolicy. |
| tests/integration/durable-objects-storage.test.js | Renames storage lifecycle tests to session policy terminology. |
| tests/integration/durable-objects-alarms.test.js | Updates alarm retargeting test naming and deploy metadata to sessionPolicy. |
| tests/fixtures/session-policy-projections.json | New cross-language fixture for session policy projection parsing/validation. |
| shared/worker-contract.js | Renames constants/helpers and projection/event codecs to session policy equivalents. |
| rust/workflows/src/api/do_alarms/dispatch.rs | Switches workflows DO-alarm routing logic to read/parse session policy projections. |
| rust/common/src/worker_contract.rs | Renames Rust-side key/projection helpers and aligns fixture-driven parsing tests. |
| gateway/websocket-lifecycle.js | Renames lifecycle reconciliation logic from rollout to session policy and updates metrics/log events. |
| gateway/runtime.js | Subscribes to session-policy:restart and routes invalidations to the new lifecycle handler. |
| docs/source-map.zh.md | Updates module ownership map terminology for session policy naming. |
| docs/source-map.md | Updates module ownership map terminology for session policy naming. |
| docs/redis-key-layout.zh.md | Documents renamed Redis keys/channels and dual-read contract for retired metadata. |
| docs/redis-key-layout.md | Documents renamed Redis keys/channels and dual-read contract for retired metadata. |
| docs/protocol-contracts.zh.md | Updates protocol ownership entry from DO rollout to session policy projection/notifications. |
| docs/protocol-contracts.md | Updates protocol ownership entry from DO rollout to session policy projection/notifications. |
| docs/modules/workflows.zh.md | Updates workflows docs to reference session policy projection reads and deployment ordering. |
| docs/modules/workflows.md | Updates workflows docs to reference session policy projection reads and deployment ordering. |
| docs/modules/gateway.zh.md | Updates gateway docs for new channel/key names and session policy semantics. |
| docs/modules/gateway.md | Updates gateway docs for new channel/key names and session policy semantics. |
| docs/modules/durable-objects.zh.md | Updates DO module docs to consume (not own) worker session policy contract and naming. |
| docs/modules/durable-objects.md | Updates DO module docs to consume (not own) worker session policy contract and naming. |
| docs/modules/control-auth.zh.md | Updates Control API docs for deploy/promote fields and Redis key ownership under session policy. |
| docs/modules/control-auth.md | Updates Control API docs for deploy/promote fields and Redis key ownership under session policy. |
| docs/compatibility.zh.md | Updates compatibility guidance for WebSocket behavior and session policy differences vs Cloudflare. |
| docs/compatibility.md | Updates compatibility guidance for WebSocket behavior and session policy differences vs Cloudflare. |
| do-runtime/protocol.js | Renames invoke fence field to sessionPolicy and ensures it is not accepted from the wire. |
| do-runtime/owner-registry.js | Renames projection key/parse logic and error codes/messages for session policy fencing. |
| do-runtime/index.js | Updates internal storage-delete invoke defaults to sessionPolicy: preserve. |
| do-runtime/actor.js | Applies restart behavior based on invoke.sessionPolicy and updates log event name/code. |
| control/routing.js | Renames routing plan structures to session policy, adds dual-read meta behavior, and restores doStorageId coherence validation. |
| control/handlers/promote.js | Returns sessionPolicy in API response and logs. |
| control/handlers/deploy.js | Rejects retired durableObjectRollout request field and persists sessionPolicy metadata. |
| control/handlers/delete.js | Deletes session policy projections during residual cleanup flows. |
| control/handlers/delete-plan.js | Deletes session policy projection and updates allocator commentary. |
| CHANGELOG.md | Documents the rename, new restart-without-DO behavior, and upgrade sequencing guidance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace the rename-narrating 400 message with the final-state contract, matching the allowedCallers precedent, and rename the deploy validation test to cover session policy input broadly. Signed-off-by: Lu Zhang <lu@wdl.dev>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 48 out of 49 changed files in this pull request and generated no new comments.
Suppressed comments (1)
control/handlers/deploy.js:368
- When rejecting the retired
durableObjectRolloutrequest field, the error message doesn’t mention the field name being rejected or that it was renamed. This makes it harder for clients to self-correct from a 400.
Consider explicitly calling out the old field and the replacement sessionPolicy name in the message.
if (body.durableObjectRollout !== undefined) {
throw invalidDeployRequest("Session policy must be declared through 'sessionPolicy'");
}
Summary
durableObjectRollouttosessionPolicyeverywhere: Control API deploy field and promote response,worker:session-policy:*/worker:session-policy-seq:*Redis keys, thesession-policy:restartchannel, gateway lifecycle log events and identifiers, JS/Rust contract helpers, shared fixture, tests, and en/zh docs. Bundle metadata persisted under the retired field is dual-read; the retired request field is rejected with 400.sessionPolicy: "restart"— a pure WebSocket worker can now opt into promote-time1012disconnects; new requests reach the promoted version under either policy.restartbehaves aspreserveuntil its next promotion.Validation
npm run lint/lint:unused/typecheck/typecheck:strict/compile:workerdnpm run test:unit— 2290 pass, including dual-read precedence/corrupt-field/bump coverage and deploy-layer plus routing-layer no-binding restart testscargo fmt --check/clippy -D warnings/test/deny checknpm run test:integration— all shards green, including the new pure-WebSocket restart promotion test1012 service restart, fresh session reaches the new version, onlyworker:session-policy*keys in Redis🤖 Generated with Claude Code