Skip to content

QueueTenancyBootstrapper

The QueueTenancyBootstrapper makes queued jobs dispatched from the context of a tenant run in the same tenant context. It does this by adding the tenant key to the job payload and listening to events related to queued jobs being processed.

In most setups, you’ll need to make slight changes to your queue configuration to make it work correctly.

Multi-database setups

If you’re using the database queue driver and the DatabaseTenancyBootstrapper, you need to ensure your queued jobs get stored in the central database. This is because you can have only one queue worker (there’s not a queue worker per tenant) so all the jobs need to be in one place even if they contain information about which tenant they should execute for.

To achieve this, force the central connection on your database queue connection:

config/queue.php
'connections' => [
'database' => [
// ...
'connection' => env('DB_CONNECTION'),
],
],

Redis queue driver

If you’re using the redis queue driver and the RedisTenancyBootstrapper, you need to use a connection that isn’t part of your configured prefixed_connections:

config/tenancy.php
'redis' => [
'prefixed_connections' => [
'default',
// 'cache',
],
],

You can check which Redis connection is being used for queued jobs in your queue config:

config/queue.php
'connections' => [
'redis' => [
'driver' => 'redis',
'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => env('REDIS_QUEUE_RETRY_AFTER', 90),
'block_for' => null,
'after_commit' => false,
],
],

Since you likely don’t have REDIS_QUEUE_CONNECTION set (and haven’t configured a new Redis connection), default will be used here.

Let’s fix that by setting this connection to queue and configuring a new connection with that name:

config/queue.php
'connections' => [
'redis' => [
'connection' => env('REDIS_QUEUE_CONNECTION', 'default'),
'connection' => 'queue',
// ...
],
],
config/database.php
'redis' => [
'queue' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
],

The configuration of the connection is identical to default, what’s important here is that it’s a separate connection and isn’t included in tenancy.redis.prefixed_connections.

Central queues

If you’d like to dispatch a central job from the tenant context, you can do this by configuring a new queue and marking it as central:

config/queue.php
'connections' => [
'central' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
'central' => true,
],
],

Then simply dispatch jobs to this queue:

dispatch(new MyJob())->onConnection('central');