Fix ancillary Marten store routing for durable local messages#2670
Closed
erdtsieck wants to merge 1 commit intoJasperFx:mainfrom
Closed
Fix ancillary Marten store routing for durable local messages#2670erdtsieck wants to merge 1 commit intoJasperFx:mainfrom
erdtsieck wants to merge 1 commit intoJasperFx:mainfrom
Conversation
542c386 to
43b2478
Compare
43b2478 to
5e44170
Compare
3 tasks
jeremydmiller
added a commit
that referenced
this pull request
May 4, 2026
…s ancillary store GH-2669 alternative to #2670. Same root cause + same primary fix on the DurableLocalQueue / DurableReceiver side (the receiving handler's ancillary store wins over the publisher-stamped envelope.Store), but the gate on FlushOutgoingMessagesOnCommit's in-transaction inbox UPDATE compares stores by Uri rather than IMessageStore.Id. Two reasons to prefer the Uri compare here: 1. The same-database fallback in the envelope.Store==null branch (GH-2382) already uses `mainStore.Uri == _messageStore.Uri`. Reusing that heuristic keeps the file's local notion of "same store" consistent and avoids introducing IMessageStore.Id as a contract surface. 2. PostgresqlMessageStore.Id is `DatabaseId(server, database)` — same DB different schema = same Id. The PR's Id-equality therefore enables a same-database cross-schema in-transaction UPDATE, which only works when the connection user has cross-schema permissions. Uri-equality (server + database + schema) is more conservative: cross-schema cases skip the in-transaction shortcut and let the envelope's owning store mark-handled through its own connection. Same end-state for the ancillary handler scenario in this issue, slightly more predictable behavior in the cross-schema case. Three changes: - DurableLocalQueue.assignAncillaryStoreIfNeeded — drop the `if (envelope.Store != null) return;` guard so the receiving handler's ancillary store overrides any store the publisher stamped. This is the primary fix; without it the publisher's main-store reference reached FlushOutgoingMessagesOnCommit and the envelopeStore.IncomingFullName branch pointed at a table that doesn't exist in the ancillary database (`42P01: relation "public.wolverine_incoming_envelopes" does not exist`). - DurableReceiver.assignAncillaryStoreIfNeeded — symmetric guard removal for the broker-receiver path. - Wolverine.Marten/FlushOutgoingMessagesOnCommit.BeforeSaveChangesAsync — in the Ancillary listener, when envelope.Store is set, only fold the handled-update into the current Marten transaction if envelopeStore.Uri matches _messageStore.Uri (same connection / schema). Cross-store envelopes return early; the envelope's owning store handles the mark-handled separately. Test: PolicyTests adopted from #2670 verbatim (Bug_2669_ancillary_marten_store_local_message_from_main_store.cs). Verified bug-present (this fix reverted) reproduces the exact `42P01: relation "public.wolverine_incoming_envelopes" does not exist` error from the issue; with the fix the test passes. 34/34 of the wider Marten ancillary / Bug_2382 / Bug_2576 / Bug_2669 subset pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2669.
Summary
Root Cause
Local durable envelopes published from a main-store handler could keep the main message store on
Envelope.Store. When the receiving handler used[MartenStore(typeof(...))]for an ancillary Marten store, the handler session still attempted to mark the envelope handled in the main/public inbox table, which can fail when that table only exists in the ancillary schema/database.Testing
dotnet test src\Persistence\MartenTests\MartenTests.csproj --filter FullyQualifiedName~Bug_ancillary_marten_store_local_message_from_main_store.durable_local_message_from_main_store_can_be_handled_by_ancillary_marten_storedotnet test src\Persistence\MartenTests\MartenTests.csproj -f net9.0 --filter FullyQualifiedName~Bug_2576_ancillary_scheduled_message_stuck_incoming --no-restore --no-build