Skip to content

Commit

Permalink
Merge pull request #301 from masterix21/feature-queue-config
Browse files Browse the repository at this point in the history
Jobs (not?) tenant aware using the config
  • Loading branch information
freekmurze authored Oct 26, 2021
2 parents a378206 + dd13fa4 commit 27eb383
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 3 deletions.
14 changes: 14 additions & 0 deletions config/multitenancy.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,18 @@
CallQueuedListener::class => 'class',
BroadcastEvent::class => 'event',
],

/*
* Jobs tenant aware even if these don't implement the TenantAware interface.
*/
'tenant_aware_jobs' => [
// ...
],

/*
* Jobs not tenant aware even if these don't implement the NotTenantAware interface.
*/
'not_tenant_aware_jobs' => [
// ...
],
];
19 changes: 17 additions & 2 deletions docs/basic-usage/making-queues-tenant-aware.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ When the behaviour is enabled, the package will keep track of which tenant is th

## Make specific jobs tenant aware

If you don't want to make all jobs tenant aware, you must set the `queues_are_tenant_aware_by_default` config key to `false`. Jobs that should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\TenantAware`.
If you don't want to make all jobs tenant aware, you must set the `queues_are_tenant_aware_by_default` config key to `false`. Jobs that should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\TenantAware` or should be added to the config `tenant_aware_jobs`.

```php
use Illuminate\Contracts\Queue\ShouldQueue;
Expand All @@ -24,9 +24,16 @@ class TestJob implements ShouldQueue, TenantAware
}
```

or, using the config `multitenancy.php`:
```php
'tenant_aware_jobs' => [
TestJob::class,
],
```

## Making specific jobs not tenant aware

Jobs that never should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\NotTenantAware`.
Jobs that never should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\NotTenantAware` or should be added to the config `not_tenant_aware_jobs`.

```php
use Illuminate\Contracts\Queue\ShouldQueue;
Expand All @@ -41,6 +48,14 @@ class TestJob implements ShouldQueue, NotTenantAware
}
```

or, using the config `multitenancy.php`:
```php
'not_tenant_aware_jobs' => [
TestJob::class,
],
```


## When the tenant cannot be retrieved

If a tenant aware job is unable to retrieve the tenant, because the tenant was deleted before the job was processed, for example, the job will fail with an instance of `Spatie\Multitenancy\Exceptions\CurrentTenantCouldNotBeDeterminedInTenantAwareJob`.
Expand Down
8 changes: 8 additions & 0 deletions src/Actions/MakeQueueTenantAwareAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ protected function isTenantAware(object $queueable): bool
return false;
}

if (in_array($reflection->name, config('multitenancy.tenant_aware_jobs'))) {
return true;
}

if (in_array($reflection->name, config('multitenancy.not_tenant_aware_jobs'))) {
return false;
}

return config('multitenancy.queues_are_tenant_aware_by_default') === true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public function it_will_not_fail_a_job_when_no_tenant_is_present_and_job_impleme
public function it_will_not_touch_the_tenant_if_the_job_is_not_tenant_aware()
{
$this->tenant->makeCurrent();

$job = new NotTenantAwareTestJob($this->valuestore);

// Simulate a tenant being set from a previous queue job
Expand Down
55 changes: 55 additions & 0 deletions tests/Feature/TenantAwareJobs/TenantAwareJobsByConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Spatie\Multitenancy\Tests\Feature\TenantAwareJobs;

use Illuminate\Contracts\Bus\Dispatcher;
use Spatie\Multitenancy\Models\Tenant;
use Spatie\Multitenancy\Tests\Feature\TenantAwareJobs\TestClasses\TestJob;
use Spatie\Multitenancy\Tests\TestCase;
use Spatie\Valuestore\Valuestore;

class TenantAwareJobsByConfig extends TestCase
{
protected Tenant $tenant;

protected Valuestore $valuestore;

public function setUp(): void
{
parent::setUp();

config()->set('multitenancy.queues_are_tenant_aware_by_default', false);
config()->set('queue.default', 'sync');
config()->set('mail.default', 'log');

$this->tenant = factory(Tenant::class)->create();
$this->valuestore = Valuestore::make($this->tempFile('tenantAware.json'))->flush();
}

/** @test */
public function it_success_with_jobs_in_tenant_aware_jobs_list(): void
{
config()->set('multitenancy.tenant_aware_jobs', [ TestJob::class ]);

$this->tenant->makeCurrent();

app(Dispatcher::class)->dispatch(new TestJob($this->valuestore));

$this->assertTrue($this->valuestore->has('tenantIdInPayload'));
$this->assertNotNull($this->valuestore->get('tenantIdInPayload'));
}

/** @test */
public function it_fails_with_jobs_in_not_tenant_aware_jobs_list(): void
{
config()->set('multitenancy.not_tenant_aware_jobs', [ TestJob::class ]);

$this->tenant->makeCurrent();

app(Dispatcher::class)->dispatch(new TestJob($this->valuestore));

$this->assertEquals($this->valuestore->get('tenantId'), $this->tenant->id);
$this->assertTrue($this->valuestore->has('tenantIdInPayload'));
$this->assertNull($this->valuestore->get('tenantIdInPayload'));
}
}
2 changes: 1 addition & 1 deletion tests/Feature/TenantAwareJobs/TestClasses/TestJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public function __construct(Valuestore $valuestore)
public function handle()
{
$this->valuestore->put('tenantIdInPayload', $this->job->payload()['tenantId'] ?? null);
$this->valuestore->put('tenantId', optional(Tenant::current())->id);
$this->valuestore->put('tenantId', Tenant::current()?->id);
}
}

0 comments on commit 27eb383

Please sign in to comment.