Fix partial batch failures causing duplicate messages in Azure Service Bus sender#2177
Merged
jeremydmiller merged 4 commits intomainfrom Feb 13, 2026
Merged
Fix partial batch failures causing duplicate messages in Azure Service Bus sender#2177jeremydmiller merged 4 commits intomainfrom
jeremydmiller merged 4 commits intomainfrom
Conversation
Replace the dependency on a real Azure subscription with the official Microsoft Azure Service Bus Emulator running locally in docker-compose, matching how all other transports (RabbitMQ, Kafka, Redis, etc.) work. Key changes: - Add ManagementConnectionString to AzureServiceBusTransport for the emulator's separate HTTP management endpoint - Add asb-sql (Azure SQL Edge) and asb-emulator services to docker-compose - Add AfterDisposeAsync() template method to TransportComplianceFixture and LeadershipElectionCompliance for per-class cleanup (stays under the emulator's 50 queue/topic limit) - Rewrite AzureServiceBusTesting to use emulator connection strings - Add emulator cleanup to all test class disposal - Move nested types from using_native_scheduling to namespace level (Azure Service Bus rejects '+' in entity names from C# nested types) 156/160 tests pass. 4 failures are emulator-specific timing differences (session ordering, topic subscription delivery, resource check semantics). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents prerequisites, dual connection strings, emulator limitations, cleanup patterns, and guidelines for writing new tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TenantedSender wraps BatchedSender instances but did not implement ISenderRequiresCallback, so RegisterCallback was never propagated to the inner BatchedSenders. This caused SendBatchAsync to throw because _callback was null, silently preventing messages from reaching Azure Service Bus. The fix makes TenantedSender implement ISenderRequiresCallback and forward the callback registration to all inner senders. Also makes WithManagementClientAsync/WithServiceBusClientAsync resilient to tenant failures during broker initialization. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e Bus sender When sending partitioned batches grouped by SessionId, a failure in one group previously marked the entire batch as failed — including groups already sent successfully. On retry this caused duplicate delivery. Same issue existed in sendBatches when splitting due to size limits. Now tracks which envelopes have been successfully sent and only marks unsent envelopes as failed on partial failure. Closes #2054. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Feb 13, 2026
This was referenced Feb 17, 2026
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.
Summary
AzureServiceBusSenderProtocolthat caused duplicate message delivery when sending partitioned (SessionId-grouped) batches or size-split batchesCloses #2054
Test plan
🤖 Generated with Claude Code