-
-
Notifications
You must be signed in to change notification settings - Fork 303
Description
Bug: Multi-tenant Postgres Transport Always Uses Wrong Sender Due to database.Name Being "Default"
Summary
When using Wolverine with a multi-tenant Postgres setup (Postgres as both the application database and the transport), the transport sender resolution fails because all tenant-specific IMessageDatabase objects get the same Name value: "Default".
Since MultiTenantedQueueSender resolves senders using:
_byDatabase.TryFind(database.Name, out sender)and database.Name is never set uniquely per tenant, every tenant’s database ends up with:
Name = "Default"
This causes Wolverine to reuse the wrong sender when processing outgoing envelopes for other tenants.
What Actually Happens
-
First tenant request arrives.
Wolverine creates aPostgresqlQueueSenderfor Tenant 1 and stores it in the dictionary:"Default" => Sender(Tenant1) -
Second tenant request arrives.
A new sender for Tenant 2 is created, but the key is again"Default", so the dictionary lookup returns the existing sender for Tenant 1. -
The Durability Agent attempts to process envelopes using the wrong database connection, leading to errors like:
InvalidOperationException: No matching outgoing envelope Sending agent for postgresql://shipment_queue/ is latched
As a result, Wolverine runs queue operations against the wrong tenant database.
Root Cause
PostgresqlTenantedMessageStore.buildTenantStoreForConnectionString() does not assign a unique name to each tenant’s IMessageDatabase.
Because of this:
- All tenant DB sources collapse into a single dictionary entry.
- Wolverine always reuses the first sender created.
- Envelope movement fails because the query runs against the wrong database.
Expected Behavior
Each tenant's IMessageDatabase should have a unique, stable name, such as:
- The tenant id, or
- A normalized connection string identifier, or
- A configured logical name.
This ensures MultiTenantedQueueSender correctly resolves the transport sender for the active tenant.
Actual Behavior
All tenants share the name "Default", causing:
- Wrong sender lookup.
- Wrong database connection usage.
- Envelope transitions failing with
InvalidOperationException: No matching outgoing envelope.
How to Reproduce
- Configure Wolverine with:
- Multi-tenant application DB (different schemas or DB servers).
- Multi-tenant Postgres transport.
- Send messages from Tenant 1 and Tenant 2.
- Observe:
-
Outbox inserts occur in the correct tenant DB.
-
The Durability Agent processes envelopes using the wrong tenant connection.
-
Errors like the following appear:
InvalidOperationException: No matching outgoing envelope
-
Impact
Multi-tenant Postgres transport becomes effectively non-functional, because messages are always routed using the wrong database connection.