Repository navigation
feat(durable-messaging): deliver application-keyed outbox intents - #11285
ReubenBond wants to merge 69 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
In-flight inbox and outbox pump turns do not revalidate callback generation and physical ownership after recovery, allowing stale callbacks to mutate current state.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (2)
What changed in this PR
Adds the durable outbox layer above the journaled inbox, including durable ownership, delivery pumping, retries, dead letters, and extensive contract/functional tests.
Changes:
- Adds journaled outbox scheduling and delivery coordination.
- Extends journaling with observer and participant lifecycle APIs.
- Adds durable messaging routing, serialization, diagnostics, and test infrastructure.
| File | Description |
|---|---|
src/Orleans.DurableMessaging/* |
Durable messaging runtime, contracts, routing, ownership, and delivery. |
src/Orleans.DurableMessaging/README.md |
Documents inbox/outbox behavior and layering. |
src/Orleans.DurableMessaging/Configuration/DurableInboxOptions.cs |
Adds messaging configuration and validation. |
src/Orleans.Journaling/IJournaledStateObserver.cs |
Adds journal boundary observer contract. |
src/Orleans.Journaling/IJournaledStateManager.cs |
Adds observer registration. |
src/Orleans.Journaling/IJournaledGrainParticipant.cs |
Adds feature participant contract. |
src/Orleans.Journaling/DurableGrain.cs |
Initializes journaled participants. |
src/api/Orleans.Journaling/Orleans.Journaling.cs |
Updates generated journaling API surface. |
test/Orleans.DurableMessaging.Tests/* |
Adds durable messaging contract, component, and functional tests. |
Orleans.slnx |
Includes durable messaging source and test projects. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Code coverage
Report-only conclusion: improved. The current-main baseline is commit Coverage combines every CI test matrix job, including providers, CodeGen, .NET 8/10, Linux, Windows, and macOS, using canonical physical source and branch identities. The comparison remains report-only while normal line and branch variance is calibrated. Coverage details |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
A recovery race can commit outbox work without scheduling a durable owner.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (2)
Resolved since last review (1)
55fd4af to
d23dabb
Compare
d23dabb to
8b4342c
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Inbox deletion does not block active interleaved pump or gate operations, allowing post-delete work or stale-generation failures.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
Resolved since last review (1)
8b4342c to
e430bf3
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Remote delivery cancellation disposes its token source while in-flight attempts may still use it, creating a concurrency failure during ownership transitions.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
Resolved since last review (1)
a30bdee to
4470a33
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Inbox owner clearing can race interleaved acceptance preparation and fence the activation instead of persisting the incoming message.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 1
Open (1)
Resolved since last review (1)
4470a33 to
e9f7764
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
The cross-cutting journaling, timer, and durable-messaging changes require final human review.
8 open findings
Recovered outbox can be persisted without a repair wake-up Removing upgrade ordering risks incorrect retries in mixed-version deployments Changing framing version breaks recovery of existing journals TargetFramework override fails in nested MSBuild invocation Required Subject field violates the opaque four-field envelope contract Preserve v1 journal compatibility during framing version change Fix article agreement in IDurableOutbox.Send documentation · New Fix incorrect article in XML summary
🧠 Review effort: Lite
| IEnumerable<DurableEnvelope> Messages { get; } | ||
|
|
||
| /// <summary> | ||
| /// Synchronously stages an command envelope for the grain's next journal write. |


Stages one immutable outgoing intent per application command key using a GC-owned
byte[]payload. Equivalent repeated staging preserves the original array; conflicting destination, ordinal subject, or bytes fails explicitly. Applications keep published arrays read-only and use distinct deterministic child keys for workflow steps and fan-out recipients. Ordinary RPC serialization and deep copying isolate receiver arrays.The final journal capture hook establishes the provider-returned physical recovery wakeup before capture. Dispatch begins after acknowledgement of the exact captured cohort; arrivals during storage await belong to the next cohort. Key-only pending records and journal-authoritative ownership preserve retry, dead-letter, cancellation, callback, and retirement outcomes.
Selected deliveries keep ordinary envelope references through actual transport and accounting outcomes. Remote batches preserve durable-attempt cancellation across timer turns and drain before disposing their token source. Test hook callbacks use an internal fixture; production features implement the journal hook interfaces directly.
Layer 3 of 4, on #11284 at
8f14ee9ed6c64fa6499cedd078f8176aaf7765c3; published headaebeff7047913b03f26651250f91bcea0247d9c1. Review only this outgoing layer. Exact contracts #11282 parent isef6a16b0ead84f52a53896cece8e90ff168fe6c5, on main42682376d80e1176a952ba13aa2de25a307b576e.Required unmerged prerequisites are journal hooks #11465 and provider-owned timers #11464. The user-closed #11468 and #11469 implementations have been removed from this stack. Arc buffers #11463, pool work #11470, and caching #11467 remain independent. Journal storage follows main's
ReadOnlySequence<byte>API, V1 writing/V0-V1 reading and configured-format recovery fallback.The staged project remains nonpackable. Typed helpers, public hosting, provider composition, samples, guides, and benchmark integration follow in #10693.