Record transport transaction state explicitly instead of inferring it#1756
Open
dvdstelt wants to merge 2 commits into
Open
Record transport transaction state explicitly instead of inferring it#1756dvdstelt wants to merge 2 commits into
dvdstelt wants to merge 2 commits into
Conversation
The dispatcher reverse-engineered the transaction mode by probing which entries happened to be present in the TransportTransaction, through an order-dependent if/else chain. Every TransportTransaction is created by code that already knows the mode, so stamp it explicitly and switch on it when dispatching. Inference remains only as a fallback for instances created outside the transport (core's empty one, hand-rolled ones). Also consolidates the ReceiveOnlyTransactionMode key, which was defined twice and only worked because both strings happened to match.
SendOptionsExtensions hand-assembled the TransportTransaction with its own copy of the key strings while PublishOptionsExtensions used the TransportTransactions factory. Use the factory in both places and drop the now-unused duplicate key from SettingsKeys.
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.
Why
I always had issues reading the many if-statements on what state/context we're in. So I created this and hope it's more readable from now on.
What
MessageDispatcher.DispatchDefaultreverse-engineered the transaction mode by probing which entries happened to be present in theTransportTransactionbag, through an order-dependent if/else chain of extension methods (OutsideOfHandler,IsNoTransaction,IsReceiveOnly,IsSendsAtomicWithReceive,IsTransactionScope). EveryTransportTransactionis created by code that already knows the mode, so this PR stamps aTransportTransactionStateinto the transaction at creation time and turns the dispatcher into a single exhaustive switch.TransportTransactionStateenum; allTransportTransactionsfactory methods record it.DispatchDefaultswitches on the state, with a comment per case explaining how sends relate to the receive transaction. The two identical "open a dedicated connection" blocks (outside handler and receive-only) collapse into one case.InferState) for instances not created by the transport: the empty one core creates for dispatches outside the message processing pipeline, and hand-rolled ones used by external integrations. It mirrors the old chain's semantics, including its ordering."SqlTransport.ReceiveOnlyTransactionMode"key was defined in two classes; the writer used one copy and the readers the other, working only because the strings happened to match. It now lives once inTransportTransactionKeysand is still written to the bag for downstream components (e.g. SQL persistence).SendOptionsExtensionshand-assembled user-provided transactions with its own copy of the key strings whilePublishOptionsExtensionsused theTransportTransactions.UserProvided(...)factory; both now use the factory, and the duplicate key was removed fromSettingsKeys.Behavior notes
No public API changes (API approval tests unchanged). One deliberate alignment: a user-provided connection-only transaction reaching default (non-immediate) dispatch previously got wrapped in a new transaction, while the same bag in isolated dispatch did not. That path is unreachable in practice because
UseCustomSqlConnection/UseCustomSqlTransactionforce immediate dispatch; both paths now behave identically (dispatch on the user's connection). Everything else is a faithful translation of the old chain.