Repository navigation
add @node-ts/bus-azure-service-bus, an azure service bus transport - #357
Open
adenhertog wants to merge 3 commits into
Open
adenhertog wants to merge 3 commits into
adenhertog wants to merge 3 commits into
Conversation
adenhertog
force-pushed
the
issue-346-azure-service-bus
branch
2 times, most recently
from
October 9, 2026 05:28
6ebf661 to
149a25f
Compare
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…us job Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
adenhertog
force-pushed
the
issue-346-azure-service-bus
branch
from
October 9, 2026 05:50
149a25f to
53ea8af
Compare
This branch has not been deployed
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 #346
Summary
Adds
@node-ts/bus-azure-service-bus, an Azure Service Bus transport that passestransportTestsagainst Microsoft's Service Bus emulator. The emulator tests run in a new CircleCI machine-executor job.Background
Azure Service Bus is the main managed broker on Azure. The issue asked for a transport built like bus-sqs, with deploy-time provisioning (#339) and the emulator in CI. The design decisions are in this comment.
Problem
There was no transport for Azure Service Bus. Some of the issue's proposals also didn't hold up against the SDK and the emulator:
maxDeliveryCountcan't be set high: the emulator only accepts 1-10.receiveMessagescalls.@azure/service-bus7.10, the JS admin client does work against the emulator, so no stubs or config-file seeding are needed.Approach
Topology: a topic per message (
resolveTopicNamedrops a leading@, replaces disallowed characters with-, and hashes names over the limits) and a queue per endpoint. Each handled topic, and each custom handler's topic, gets a subscription named after the queue that forwards into it.Receiving:
subscribe()withmaxConcurrentCalls=concurrencyfeedsreadNextMessage(). Each callback is held until the bus settles the message, so the SDK keeps renewing the lock (lockDurationPT1M, auto-renewal 5 min).stop()abandons messages that were delivered but not read.Retries:
returnMessageschedules a copy at now + delay withfailedAttempts+ 1 and native id<messageId>:<attempt>, then completes the original.deliveryCountis ignored, andmaxDeliveryCount(10) only catches crash loops.Dead-lettering: native
deadLetterMessagewithbus-failure, a reason and a description. The queue and its subscriptions forward dead letters to the shareddeadLetterQueueName. The forwarded copy keepsbus-failureand the headers (verified on the emulator), so the copy-then-complete fallback wasn't needed.Provisioning:
provision()uses the admin client and needs Manage. It throwsAzureServiceBusTierNotSupportedon the Basic tier and treats 409 as success. It then updates forwarding and lock settings that differ. A dry run makes no calls.Runtime plan: format
azure-rbac, with role assignments scoped relative to the namespace:verifySubscriptions.Startup checks:
initialize()peeks the queue (Listen only). The opt-inverifySubscriptionsalso checks the dead letter queue and the subscriptions through the admin client.Auth and clients:
connectionString, orfullyQualifiedNamespace+TokenCredential, with an optional injectedServiceBusClientand admin client. There's no@azure/identitydependency.Errors and replies:
AzureServiceBusMessageTooLargefor over-size messages,ResourcesNotProvisionedfor a missing topic, andEndpointNotFoundfor a reply to a missing queue. Replies go straight to the queue in the same namespace.Infra:
docker-compose.ymlhas the emulator and SQL Server behind theazure-service-busprofile, on host ports 5673 (AMQP) and 5300, with pinned images and an empty-namespace config.azure-service-busCircleCI job runs the emulator withdocker composeon a machine executor and waits on/health. The build job's integration run leaves this package out, and deploy requires both jobs.Docs:
/transports/azure-service-buswith its snippets and sidebar entry, plus rows in the provisioning, recoverability and middleware tables, the package README andCLAUDE.md, and the root README andCLAUDE.md.Tests: unit tests over typemoq-mocked clients, and integration tests against the emulator: the shared suite, missing resources, a dry run, resyncing a subscription, headers, the size limit and replies. Every entity is cleaned up.
Not included: sessions, the follow-up the issue names.
This is original work under the clean-room policy, not ported, translated or copied from another messaging framework
Added a changeset (
pnpm changeset) for user-facing changes to published packages, or none is neededDocs: updated
docs/for user-facing changes, or none needed🤖 Generated with Claude Code