Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TenantAware and NotTenantAware are not detected in MakeQueueTenantAwareAction #81

Closed
3assy2018 opened this issue Jul 14, 2020 · 2 comments

Comments

@3assy2018
Copy link
Contributor

3assy2018 commented Jul 14, 2020

There's a problem I noticed when I was working on a project is that there's some unexpected behavior happens in queues, at which I try to implement NotTenantAware or TenantAware and switch the queues_are_tenant_aware_by_default key, and then I realize that there's a problem happens on the other side, meaning that if the tenant side is fixed, the landlord side crashes in queues and vice versa.

Env:

  • PHP 7.4.8
  • Laravel 7.0
  • OS: Windows
  • Local Server Client: Laragon
namespace App\Listeners\Landlord;

use App\Events\Landlord\TenantCreated;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Artisan;
use Spatie\Multitenancy\Jobs\NotTenantAware;

class OnTenantCreated implements ShouldQueue, NotTenantAware
{
    public $queue = 'tenants_db';
    public function __construct()
    {
        //
    }
    public function handle(TenantCreated $event)
    {
        Artisan::call(
          "tenants:artisan \"migrate --database=tenant --seed\" --tenant={$event->tenant->id}"
        );
    }
}

this code is Landlord Specific Event Listener

namespace App\Listeners\Tenant;

use App\Events\Tenant\UserCreated;
use App\Mail\UserCreatedMail;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;
use Spatie\Multitenancy\Jobs\TenantAware;

class OnUserCreated implements ShouldQueue, TenantAware
{
    public $queue = 'tenants_mail';
    public function __construct()
    {
        //
    }
    public function handle(UserCreated $event)
    {
        Mail::to($event->user)->send(new UserCreatedMail($event->user));
    }
}

and this one is tenant specific.

However, when I switch the key in config one works and one crashes, but I noticed something happened also.
When I tried to use Tinker or Web to inspect those Listeners Implementations I got the right implementation Like following:

Tinker:

class_implements(\App\Listeners\Landlord\OnTenantCreated::class)

//Output

[
     "Illuminate\Contracts\Queue\ShouldQueue" => "Illuminate\Contracts\Queue\ShouldQueue",
     "Spatie\Multitenancy\Jobs\NotTenantAware" => "Spatie\Multitenancy\Jobs\NotTenantAware",
]

Web:

use App\Listeners\Landlord\OnTenantCreated;

Route::get('/reflect', function (){
    return class_implements(OnTenantCreated::class);
});

Output: 

{
"Illuminate\\Contracts\\Queue\\ShouldQueue": "Illuminate\\Contracts\\Queue\\ShouldQueue",
"Spatie\\Multitenancy\\Jobs\\NotTenantAware": "Spatie\\Multitenancy\\Jobs\\NotTenantAware"
}

And then I tried to Log Listener implementations to errors log file and I noticed something very very weird:

[2020-07-14 13:08:49] local.INFO: array (
  'Illuminate\\Contracts\\Queue\\ShouldQueue' => 'Illuminate\\Contracts\\Queue\\ShouldQueue',
)  
[2020-07-14 13:08:52] local.ERROR: The current tenant could not be determined in a job named `Illuminate\Queue\CallQueuedHandler@call`. No `tenantId` was set in the payload. {"exception":"[object] (Spatie\\Multitenancy\\Exceptions\\CurrentTenantCouldNotBeDeterminedInTenantAwareJob(code: 0): The current tenant could not be determined in a job named `Illuminate\\Queue\\CallQueuedHandler@call`. No `tenantId` was set in the payload. at C:\\laragon\\www\\test-mt\\vendor\\spatie\\laravel-multitenancy\\src\\Exceptions\\CurrentTenantCouldNotBeDeterminedInTenantAwareJob.php:12)
[stacktrace]
#0 C:\\laragon\\www\\test-mt\\vendor\\spatie\\laravel-multitenancy\\src\\Actions\\MakeQueueTenantAwareAction.php(83): Spatie\\Multitenancy\\Exceptions\\CurrentTenantCouldNotBeDeterminedInTenantAwareJob::noIdSet(Object(Illuminate\\Queue\\Events\\JobProcessing))
#1 C:\\laragon\\www\\test-mt\\vendor\\spatie\\laravel-multitenancy\\src\\Actions\\MakeQueueTenantAwareAction.php(48): Spatie\\Multitenancy\\Actions\\MakeQueueTenantAwareAction->findTenant(Object(Illuminate\\Queue\\Events\\JobProcessing))
#2 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Events\\Dispatcher.php(381): Spatie\\Multitenancy\\Actions\\MakeQueueTenantAwareAction->Spatie\\Multitenancy\\Actions\\{closure}(Object(Illuminate\\Queue\\Events\\JobProcessing))
#3 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Events\\Dispatcher.php(226): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}('Illuminate\\\\Queu...', Array)
#4 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(512): Illuminate\\Events\\Dispatcher->dispatch('Illuminate\\\\Queu...')
#5 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(343): Illuminate\\Queue\\Worker->raiseBeforeJobEvent('database', Object(Illuminate\\Queue\\Jobs\\DatabaseJob))
#6 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(306): Illuminate\\Queue\\Worker->process('database', Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Object(Illuminate\\Queue\\WorkerOptions))
#7 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Worker.php(132): Illuminate\\Queue\\Worker->runJob(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), 'database', Object(Illuminate\\Queue\\WorkerOptions))
#8 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Console\\WorkCommand.php(112): Illuminate\\Queue\\Worker->daemon('database', 'tenants_db', Object(Illuminate\\Queue\\WorkerOptions))
#9 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Console\\WorkCommand.php(96): Illuminate\\Queue\\Console\\WorkCommand->runWorker('database', 'tenants_db')
#10 [internal function]: Illuminate\\Queue\\Console\\WorkCommand->handle()
#11 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(33): call_user_func_array(Array, Array)
#12 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Util.php(37): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#13 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(91): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#14 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(35): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#15 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php(592): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#16 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(134): Illuminate\\Container\\Container->call(Array)
#17 C:\\laragon\\www\\test-mt\\vendor\\symfony\\console\\Command\\Command.php(258): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#18 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(121): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#19 C:\\laragon\\www\\test-mt\\vendor\\symfony\\console\\Application.php(911): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#20 C:\\laragon\\www\\test-mt\\vendor\\symfony\\console\\Application.php(264): Symfony\\Component\\Console\\Application->doRunCommand(Object(Illuminate\\Queue\\Console\\WorkCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#21 C:\\laragon\\www\\test-mt\\vendor\\symfony\\console\\Application.php(140): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#22 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Application.php(93): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#23 C:\\laragon\\www\\test-mt\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Console\\Kernel.php(129): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#24 C:\\laragon\\www\\test-mt\\artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#25 {main}
"} 

As the result shows, it does not detect TenantAware or NotTenantAware interfaces from inside MakeQueueTenantAwareAction

protected function listenForJobsBeingQueued(): self
    {
        app('queue')->createPayloadUsing(function ($connectionName, $queue, $payload) {
            $job = $payload['data']['command'];

            Log::info(class_implements($job));

            if (! $this->isTenantAware($job)) {
                return [];
            }

            return ['tenantId' => optional(Tenant::current())->id];
        });

        return $this;
    }

Solutions I tried:

  • composer dump-autoload
  • php artisan optimize
  • php artisan config:clear
  • php artisan cache:clear
  • php artisan queue:restart
  • Restarted local web server
  • Restarted tinker
  • Restarted the whole computer
@ivalkenburg
Copy link

#78 should fix this issue.

@freekmurze
Copy link
Member

We'll take a look at #78 soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants