1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-05 15:34:04 +00:00

Setting $deleteWhenCannotIdentify property deletes the job if it could not be initialized

Signed-off-by: michael.lundb <>
This commit is contained in:
michael.lundb 2022-02-22 13:14:14 +01:00
parent 5b9b384526
commit e28060f4fd
2 changed files with 84 additions and 5 deletions

View file

@ -7,6 +7,7 @@ namespace Stancl\Tenancy\Bootstrappers;
use Illuminate\Support\Str;
use Illuminate\Config\Repository;
use Illuminate\Queue\QueueManager;
use ReflectionClass;
use Stancl\Tenancy\Contracts\Tenant;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Queue\Events\JobProcessed;
@ -16,6 +17,8 @@ use Illuminate\Queue\Events\JobRetryRequested;
use Illuminate\Support\Testing\Fakes\QueueFake;
use Illuminate\Contracts\Foundation\Application;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Exceptions\TenancyNotInitializedException;
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedById;
class QueueTenancyBootstrapper implements TenancyBootstrapper
{
@ -58,7 +61,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
$dispatcher->listen(JobProcessing::class, function ($event) use (&$previousTenant) {
$previousTenant = tenant();
static::initializeTenancyForQueue($event->job->payload()['tenant_id'] ?? null);
static::initializeTenancyForQueue($event);
});
if (Str::startsWith(app()->version(), '8')) {
@ -66,7 +69,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
$dispatcher->listen(JobRetryRequested::class, function ($event) use (&$previousTenant) {
$previousTenant = tenant();
static::initializeTenancyForQueue($event->payload()['tenant_id'] ?? null);
static::initializeTenancyForQueue($event);
});
}
@ -81,8 +84,11 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
$dispatcher->listen(JobFailed::class, $revertToPreviousState); // artisan('queue:work') which fails
}
protected static function initializeTenancyForQueue($tenantId)
protected static function initializeTenancyForQueue($event)
{
$tenantId = $event->payload()['tenant_id'] ?? null;
if (! $tenantId) {
// The job is not tenant-aware
if (tenancy()->initialized) {
@ -99,7 +105,11 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
tenancy()->end();
}
tenancy()->initialize(tenancy()->find($tenantId));
try {
tenancy()->initialize($tenantId);
} catch (TenantCouldNotBeIdentifiedById $e) {
static::handleTenantCouldNotBeFound($event->job, $e);
}
return;
}
@ -114,7 +124,11 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
// Tenancy was either not initialized, or initialized for a different tenant.
// Therefore, we initialize it for the correct tenant.
tenancy()->initialize(tenancy()->find($tenantId));
try {
tenancy()->initialize($tenantId);
} catch (TenantCouldNotBeIdentifiedById $e) {
static::handleTenantCouldNotBeFound($event->job, $e);
}
}
protected static function revertToPreviousState($event, &$previousTenant)
@ -148,6 +162,25 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper
}
}
protected static function handleTenantCouldNotBeFound($job, \Throwable $e)
{
$class = $job->resolveName();
try {
$shouldDelete = (new ReflectionClass($class))
->getDefaultProperties()['deleteWhenCannotIdentify'] ?? false;
} catch (\Throwable $e) {
$shouldDelete = false;
}
if ($shouldDelete) {
return $job->delete();
}
return $job->fail($e);
}
public function bootstrap(Tenant $tenant)
{
//

View file

@ -244,6 +244,30 @@ class QueueTest extends TestCase
$this->assertSame('The current tenant id is: acme', $this->valuestore->get('tenant_id'));
}
/** @test */
public function job_can_be_when_not_initialized_inside_queues()
{
$tenant = Tenant::create([
'id' => 'acme',
]);
tenancy()->initialize($tenant);
dispatch(new TestJobDeleted($this->valuestore));
$this->assertEquals(1, \Illuminate\Support\Facades\Queue::size());
$this->assertFalse($this->valuestore->has('tenant_id'));
tenancy()->end();
$tenant->delete();
$this->artisan('queue:work --once');
$this->assertFalse($this->valuestore->has('tenant_id'));
$this->assertEquals(0, \Illuminate\Support\Facades\Queue::size());
}
}
class TestJob implements ShouldQueue
@ -281,3 +305,25 @@ class TestJob implements ShouldQueue
}
}
}
class TestJobDeleted implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/** @var Valuestore */
protected $valuestore;
public $deleteWhenCannotIdentify = true;
public function __construct(Valuestore $valuestore)
{
$this->valuestore = $valuestore;
}
public function handle()
{
$this->valuestore->put('tenant_id', tenant('id'));
}
}