-
-
Couldn't load subscription status.
- Fork 370
Description
Hello - I wanted to sanity check how I plan to implement rebus in our multitenant application
My application has multiple tenants
Some tenants may share the same database (TenantId is used in tables)
Other tenants may have their own isolated database (TenantId is still used but only ever contains a single tenants data)
I have a DI container per tenant
when the app starts, it starts all the tenants, and this means building each tenants DI container from configuration and tenant configuration will have a sql connection string for that tenant, sometimes multiple tenants have the same connection string, sometimes they have their own one.
I have a single transport (service bus) configured for the entire application - typically tenants will either all share a single queue for some purpose, or if they need their own queues, I prefix the queue name with the tenant guid.
I am now thinking about whether I can fit rebus into this architecture.
My first thought is to do this:
- Create a rebus instance (bus) per tenant, and add it into each tenants DI container. The outboxwill be configured with that tenants database connection string.
However this hits a problem: If there are two tenants sharing a connection string, won't that mean two bus instances, both configured with an outbox pointing to the same outbox tables? Could this mean both buses try to process records from there and dispatch to the transport - and could this cause an issue? In reality its not 2 tenants that can be sharing its ~100. It doesnt look like the outbox allows you to use a filter (i.e TenantId =1) or anything like that.
The outbox does really complicate things as it has to sit in the tenant database as that is where the tenants transactional data is held, so I think this means that there is no getting around the fact that I need a separate outbox based on the tenant context.
I think my ideal solution would be if I could achieve something like this though
- Add a single top level bus instance that corresponds with the single transport for the app (service bus) - rather than having a bus per tenant (i.e in each tenants DI container).
- Be able to tell rebus to dynamically select the outbox to use
- when its handling a message, I think it sets up the sqlconnection and transaction from the outbox connection string - i'd want have it select the "right" one based on the tenant id of the message..
- outside of a message handler, it looks like the application has to provide the sql connection to use anyway so this seems easier: https://github.com/rebus-org/Rebus/wiki/Outbox#2-when-youre-not-in-a-rebus-handler
So for example:-
- if I am handling a message and the tenant context is 1, then the outbox can use the sql connection for tenant 1.
- If I am publishing a message (outside of a handler) and the tenant context is 2, then the outbox can use the sql connection for tenant 2.
However I am not sure whether this is achievable. I guess there has to be some background service monitoring these database tables in order to forward messages to the transport and I guess that would need to be able to monitor accross all the databases.
Appreciate any tips on this anyone can give. Many thanks