Skip to content

[Mocha] Fix the outbox worker missing messages written inside a TransactionScope - #10496

Merged
tobias-tengler merged 6 commits into
mainfrom
tte/mocha-outbox-ambient-transaction-signal
Oct 6, 2026
Merged

tobias-tengler merged 6 commits into
mainfrom
tte/mocha-outbox-ambient-transaction-signal

Conversation

@tobias-tengler

Copy link
Copy Markdown
Member

Outbox writes inside a TransactionScope signal the outbox worker before the transaction commits, and nothing signals it at commit. The worker wakes, finds no visible rows, and waits indefinitely, so the committed message is only dispatched after an unrelated write.

This PR defers the signal until the ambient transaction completes, for both outbox inserts and SaveChanges.

Outbox writes inside a TransactionScope signal the outbox worker before
the row is committed and never signal at commit, so the worker can park
indefinitely with a committed message in the table.
Outbox writes and SaveChanges inside a TransactionScope now set the
outbox signal when the ambient transaction completes instead of
immediately, so the worker no longer wakes before the row is visible
and parks with a committed message in the table.
Persisting many outbox messages in one TransactionScope no longer adds
a completion handler per message, and a signal disposed during shutdown
no longer throws out of the committed scope's Dispose.
Drop the per-transaction subscription tracking and the disposed-signal
guard. Repeated signals collapse in the auto-reset event, so one
completion handler per write is sufficient.
Copilot AI balanced review requested due to automatic review settings October 6, 2026 20:30
@github-actions github-actions Bot added the 📚 documentation This issue is about working on our documentation. label Oct 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

Static review found no blocking issues, and regression tests cover both write paths and transaction completion, though they were not executed.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes Mocha outbox wakeups so messages written inside a TransactionScope can be dispatched after commit without waiting for another write.

Changes:

  • Defers insert and SaveChanges signals until ambient transaction completion.
  • Adds regression tests for commit, rollback, multiple messages, and worker delivery.
File Description
src/​Mocha/​test/​Mocha.EntityFrameworkCore.Postgres.Tests/​PostgresOutboxAmbientTransactionSignalTests.cs Adds transaction signaling and delivery tests.
src/​Mocha/​src/​Mocha.EntityFrameworkCore/​Outbox/​OutboxSignalExtensions.cs Centralizes deferred signaling.
src/​Mocha/​src/​Mocha.EntityFrameworkCore/​Outbox/​OutboxSaveChangesInterceptor.cs Defers signals after SaveChanges.
src/​Mocha/​src/​Mocha.EntityFrameworkCore/​Assembly.cs Exposes the internal helper to the Postgres assembly.
src/​Mocha/​src/​Mocha.EntityFrameworkCore.Postgres/​Outbox/​PostgresMessageOutbox.cs Defers insert signals and updates documentation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The Postgres transport's own ThrowHelper shadows Mocha.ThrowHelper, which
defines BeforeAndAfterConflict, so the build failed.
@tobias-tengler
tobias-tengler merged commit 5d2aa77 into main Oct 6, 2026
155 checks passed
@tobias-tengler
tobias-tengler deleted the tte/mocha-outbox-ambient-transaction-signal branch October 6, 2026 20:49
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Patch coverage

90.9% of changed lines covered (10/11)

File Covered Changed Patch %
…/Descriptors/PostgresQueueDescriptor.cs 0 1 0.0% 🔴
…/Outbox/PostgresMessageOutbox.cs 1 1 100.0% 🟢
…/Outbox/OutboxSaveChangesInterceptor.cs 1 1 100.0% 🟢
…/Mocha.EntityFrameworkCore/Outbox/OutboxSignalExtensions.cs 8 8 100.0% 🟢
Uncovered changed lines (JSON)
{
  "sha": "3f739125d6343fe71635cbc57af52b54d0faa6ac",
  "files": [
    { "path": "src/Mocha/src/Mocha.Transport.Postgres/Descriptors/PostgresQueueDescriptor.cs", "ranges": [[127, 127]] }
  ]
}

Project coverage: 58.5% (313834/536121 lines)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📚 documentation This issue is about working on our documentation. 🌶️ mocha

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants