Skip to content

Commit 4c8a6f3

Browse files
committed
Bring back MakeQueueTenantAwareAction
1 parent 61a6a86 commit 4c8a6f3

3 files changed

Lines changed: 79 additions & 37 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace ProcessMaker\Multitenancy;
4+
5+
use Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction as BaseMakeQueueTenantAwareAction;
6+
7+
class MakeQueueTenantAwareAction extends BaseMakeQueueTenantAwareAction
8+
{
9+
/**
10+
* We're handling tenant aware queues manually, however, we still need to implement this because for some
11+
* reason the Spatie package calls it in Multitenancy::start(), weather it's a configured action or not.
12+
*/
13+
public function execute() : void
14+
{
15+
// Do nothing
16+
}
17+
}

ProcessMaker/Providers/ProcessMakerServiceProvider.php

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Illuminate\Notifications\Events\NotificationSent;
1212
use Illuminate\Queue\Events\JobAttempted;
1313
use Illuminate\Queue\Events\JobProcessing;
14+
use Illuminate\Queue\Events\JobRetryRequested;
1415
use Illuminate\Support\Arr;
1516
use Illuminate\Support\Env;
1617
use Illuminate\Support\Facades;
@@ -236,52 +237,75 @@ public function register(): void
236237
}
237238

238239
/**
239-
* Register app-level events.
240+
* In multitenancy, we need to bootstrap a new app with the tenant id set.
241+
* This is because queue workers are long-running processes that are not
242+
* tenant aware.
240243
*/
241-
protected static function registerEvents(): void
244+
private static function bootstrapTenantApp(JobProcessing|JobRetryRequested $event): void
242245
{
243-
Facades\Event::listen(JobProcessing::class, function ($event) {
244-
Context::hydrate($event->job->payload()['illuminate:log:context'] ?? null);
245-
$tenantId = Context::get(config('multitenancy.current_tenant_context_key'));
246-
if ($tenantId) {
247-
if (!method_exists($event->job, 'getRedisQueue')) {
248-
// Not a redis job
249-
return;
250-
}
246+
Context::hydrate($event->job->payload()['illuminate:log:context'] ?? null);
247+
$tenantId = Context::get(config('multitenancy.current_tenant_context_key'));
248+
if ($tenantId) {
249+
if (!method_exists($event->job, 'getRedisQueue')) {
250+
// Not a redis job
251+
return;
252+
}
251253

252-
// Save the landlord's config values so we can reset them later
253-
if (self::$landlordValues === null) {
254-
foreach (TenantBootstrapper::$landlordKeysToSave as $key) {
255-
self::$landlordValues[$key] = $_SERVER[$key] ?? '';
256-
}
254+
// Save the landlord's config values so we can reset them later
255+
if (self::$landlordValues === null) {
256+
foreach (TenantBootstrapper::$landlordKeysToSave as $key) {
257+
self::$landlordValues[$key] = $_SERVER[$key] ?? '';
257258
}
259+
}
258260

259-
// Create a new tenant app instance
260-
$_SERVER['TENANT'] = $tenantId;
261-
$_ENV['TENANT'] = $tenantId;
262-
$tenantApp = require app()->bootstrapPath('app.php');
263-
$tenantApp->instance('landlordValues', self::$landlordValues);
264-
$tenantApp->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
261+
// Create a new tenant app instance
262+
$_SERVER['TENANT'] = $tenantId;
263+
$_ENV['TENANT'] = $tenantId;
264+
$tenantApp = require app()->bootstrapPath('app.php');
265+
$tenantApp->instance('landlordValues', self::$landlordValues);
266+
$tenantApp->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
265267

266-
// Change the job's app service container to the tenant app
267-
$event->job->getRedisQueue()->setContainer($tenantApp);
268-
}
269-
});
268+
// Change the job's app service container to the tenant app
269+
$event->job->getRedisQueue()->setContainer($tenantApp);
270+
}
271+
}
270272

271-
Facades\Event::listen(JobAttempted::class, function ($event) {
272-
if (!method_exists($event->job, 'getRedisQueue')) {
273-
// Not a redis job
274-
return;
275-
}
273+
private static function resetTenantApp($event): void
274+
{
275+
if (!method_exists($event->job, 'getRedisQueue')) {
276+
// Not a redis job
277+
return;
278+
}
276279

277-
unset($_SERVER['TENANT']);
278-
unset($_ENV['TENANT']);
280+
unset($_SERVER['TENANT']);
281+
unset($_ENV['TENANT']);
279282

280-
// Restore the original values since the tenant boostrapper modified them
281-
foreach (self::$landlordValues as $key => $value) {
282-
$_SERVER[$key] = $value;
283-
$_ENV[$key] = $value;
284-
}
283+
if (!self::$landlordValues) {
284+
return;
285+
}
286+
287+
// Restore the original values since the tenant boostrapper modified them
288+
foreach (self::$landlordValues as $key => $value) {
289+
$_SERVER[$key] = $value;
290+
$_ENV[$key] = $value;
291+
}
292+
}
293+
294+
/**
295+
* Register app-level events.
296+
*/
297+
protected static function registerEvents(): void
298+
{
299+
Facades\Event::listen(JobProcessing::class, function (JobProcessing $event) {
300+
self::bootstrapTenantApp($event);
301+
});
302+
303+
Facades\Event::listen(JobRetryRequested::class, function (JobRetryRequested $event) {
304+
self::bootstrapTenantApp($event);
305+
});
306+
307+
Facades\Event::listen(JobAttempted::class, function (JobAttempted $event) {
308+
self::resetTenantApp($event);
285309
});
286310

287311
// Listen to the events for our core screen

config/multitenancy.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
'actions' => [
8888
'make_tenant_current_action' => MakeTenantCurrentAction::class,
8989
'forget_current_tenant_action' => ForgetCurrentTenantAction::class,
90+
'make_queue_tenant_aware_action' => ProcessMaker\Multitenancy\MakeQueueTenantAwareAction::class,
9091
'migrate_tenant' => MigrateTenantAction::class,
9192
],
9293

0 commit comments

Comments
 (0)