Skip to content

Comments

Fix partial batch failures causing duplicate messages in Azure Service Bus sender#2177

Merged
jeremydmiller merged 4 commits intomainfrom
azure-testing
Feb 13, 2026
Merged

Fix partial batch failures causing duplicate messages in Azure Service Bus sender#2177
jeremydmiller merged 4 commits intomainfrom
azure-testing

Conversation

@jeremydmiller
Copy link
Member

Summary

  • Fixes partial batch failure handling in AzureServiceBusSenderProtocol that caused duplicate message delivery when sending partitioned (SessionId-grouped) batches or size-split batches
  • Preserves envelope-to-ServiceBusMessage correlation so successfully sent messages are tracked independently
  • On partial failure, only unsent envelopes are marked as failed and retried; already-sent envelopes are marked successful

Closes #2054

Test plan

  • Build compiles with zero errors
  • Existing Azure Service Bus integration tests pass (require emulator via docker-compose)
  • Verify no duplicate messages when a session group fails mid-batch

🤖 Generated with Claude Code

jeremydmiller and others added 4 commits February 13, 2026 08:37
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Azure Service Bus partitioned batching: Partial batch failures may cause duplicate messages or incorrect failure handling

1 participant