Skip to content

Fix PrefixIdentifiers not applied to GlobalPartitioned slot endpoints#2624

Merged
jeremydmiller merged 1 commit into
JasperFx:mainfrom
sudosanet:fix/partitioned-topology-prefix
Apr 29, 2026
Merged

Fix PrefixIdentifiers not applied to GlobalPartitioned slot endpoints#2624
jeremydmiller merged 1 commit into
JasperFx:mainfrom
sudosanet:fix/partitioned-topology-prefix

Conversation

@sudosanet

Copy link
Copy Markdown
Contributor

Summary

I ran into this combining PrefixIdentifiers with the global partitioning
feature added in #2273. With both enabled, the partitioned slot endpoints get
registered with the un-prefixed base name while listeners for the same
shards correctly get the prefix applied. At broker startup the slot endpoint's
GetQueueUrl looks up {baseName}{N} instead of {prefix}-{baseName}{N} and
the entire transport fails to initialize:

Wolverine.AmazonSqs.WolverineSqsTransportException: Error while trying to
  initialize Amazon SQS queue 'snap-action4'
  ---> Amazon.SQS.Model.QueueDoesNotExistException: The specified queue does not exist.
...
Wolverine.Transports.BrokerInitializationException: Unable to initialize the Broker sqs in time

Root cause

PartitionedMessageTopology<> (base) calls the transport-specific
buildEndpoint(options, name) for each shard slot in its constructor. For
every transport that implements PrefixIdentifiers, buildEndpoint routes
through the endpoint cache directly, bypassing MaybeCorrectName:

// e.g. Wolverine.AmazonSqs
protected override Endpoint buildEndpoint(WolverineOptions options, string name)
{
    return options.AmazonSqsTransport().Queues[name];  // un-prefixed
}

Meanwhile buildListener / buildSubscriber go through the public
ListenTo* / To* helpers, which DO call MaybeCorrectName. The result is
two different cache entries per shard:

  • {baseName}{N} — slot endpoint (un-prefixed), does not exist in the broker
  • {prefix}-{baseName}{N} — listener endpoint (prefixed), matches the real queue/topic

Both endpoints are initialized at broker startup, and the un-prefixed slot
endpoint's GetQueueUrl call fails because no such queue exists.

Fix

Apply MaybeCorrectName in buildEndpoint so slot and listener resolve to
the same prefixed cache entry. Identical 1-line shape across the four affected
transports (SQS, Azure Service Bus, RabbitMQ, GCP Pub/Sub):

 protected override Endpoint buildEndpoint(WolverineOptions options, string name)
 {
-    return options.XxxTransport().Queues[name];
+    var transport = options.XxxTransport();
+    return transport.Queues[transport.MaybeCorrectName(name)];
 }

NATS / Kafka / Pulsar / Redis don't trigger this mismatch — they don't
reference MaybeCorrectName anywhere, so buildEndpoint and buildListener
are already consistent (both un-prefixed) for those transports.

Test plan

  • Added sharded_topology_with_prefix.prefix_is_applied_to_sharded_slot_endpoints in Wolverine.AmazonSqs.Tests — fails on main (un-prefixed slots leak), passes after the fix. Inspects options synchronously without starting the host, so no LocalStack required.
  • All four affected transport projects build clean.
  • Existing E2E suites for SQS / ASB / Rabbit / GCP — most need real broker infrastructure I don't have running locally; CI should cover.

@jeremydmiller jeremydmiller merged commit 1f294ce into JasperFx:main Apr 29, 2026
20 of 21 checks passed
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.

2 participants