spatie / laravel-multitenancy

Make your Laravel app usable by multiple tenants
https://spatie.be/docs/laravel-multitenancy
MIT License
1.13k stars 152 forks source link

base table or view not found with AWS SQS queue for job TenantAware #505

Closed MattWiseParking closed 2 months ago

MattWiseParking commented 11 months ago

Hi

I am receiving intermittent issues with a job that sometimes it works sometimes it doesnt. I receive the following error:

Base table or view not found: 1146 Table 'db_lgnhs.tenants' doesn't exist (Connection: landlord, SQL: select * from `tenants` where `tenants`.`id` = 3 limit 1)

The field in my multitenancy is set:

'queues_are_tenant_aware_by_default' => false,

The Job class:

class ProcessAnprFactoryJob implements ShouldQueue,TenantAware
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $carparkAnprRead;

    public $carparkCamera;

    public $vehicle;
    /**
     * Create a new job instance.
     */
    public function __construct($carparkAnprRead,$carparkCamera,$vehicle)
    {
        $this->carparkAnprRead = $carparkAnprRead;
        $this->carparkCamera = $carparkCamera;
        $this->vehicle = $vehicle;
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {

        //do some coding
        activity('ANPR API')->log('the anpr factory job has started');
        $factory = new AnprFactory();
        $factory->process($this->carparkAnprRead, $this->carparkCamera,$this->vehicle);
        activity('ANPR APIP')->log('the anpr factory job has ended');
    }

    /**
     * Handle a job failure.
     */
    public function failed(Throwable $exception): void
    {
        activity('ANPR API')->log('Failed: '.$exception->getMessage());
    }
}

Sometimes the job fails with the above error and some times it doesnt, its a but hit and miss, more recently the job has failed There is no other jobs execute inside the $factory->process code

I am using:

Laravel version 10.13.5 spatie multi tenancy version: 3.0.3

the client calling the above job is in fact in the api routes, several tests that the tenant id is being called correctly from this code.

Struggling to understand why its causing intermittent issues? should i pass the tenant ID to the job, and make the job NotTenantAware then in the code just call $tenant = app('currentTenant'); $tenant->id

masterix21 commented 10 months ago

Hi @MattWiseParking

What is your default connection?

MattWiseParking commented 10 months ago

My Default connection is mysql. I have 3 connections setup:

see my config/database.php file below:

'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        'landlord' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

        'tenant' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => null,
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
MattWiseParking commented 10 months ago

dump of the error below:

Connection Name: Exception: PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db_lgnhs.tenants' doesn't exist in /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416 Stack trace: #0 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(416): PDO->prepare('select * from ...') #1 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(788): Illuminate\Database\Connection->Illuminate\Database\{closure}('select * from ...', Array) #2 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(934): Illuminate\Database\Connection->runQueryCallback('select * from ...', Array, Object(Closure)) #3 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(914): Illuminate\Database\Connection->tryAgainIfCausedByLostConnection(Object(Illuminate\Database\QueryException), 'select * from ...', Array, Object(Closure)) #4 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(758): Illuminate\Database\Connection->handleQueryException(Object(Illuminate\Database\QueryException), 'select * from ...', Array, Object(Closure)) #5 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(424): Illuminate\Database\Connection->run('select * from ...', Array, Object(Closure)) #6 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2736): Illuminate\Database\Connection->select('select * from `...', Array, true) #7 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2724): Illuminate\Database\Query\Builder->runSelect() #8 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3278): Illuminate\Database\Query\Builder->Illuminate\Database\Query{closure}() #9 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2725): Illuminate\Database\Query\Builder->onceWithColumns(Array, Object(Closure)) #10 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(717): Illuminate\Database\Query\Builder->get(Array) #11 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(701): Illuminate\Database\Eloquent\Builder->getModels(Array) #12 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php(296): Illuminate\Database\Eloquent\Builder->get(Array) #13 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(443): Illuminate\Database\Eloquent\Builder->first(Array) #14 /var/app/current/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\Database\Eloquent\Builder->find(3) #15 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2335): Illuminate\Database\Eloquent\Model->forwardCallTo(Object(Illuminate\Database\Eloquent\Builder), 'find', Array) #16 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2347): Illuminate\Database\Eloquent\Model->__call('find', Array) #17 /var/app/current/vendor/spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php(105): Illuminate\Database\Eloquent\Model::__callStatic('find', Array) #18 /var/app/current/vendor/spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php(132): Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction->findTenant(Object(Illuminate\Queue\Events\JobProcessing)) #19 /var/app/current/vendor/spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php(46): Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction->bindOrForgetCurrentTenant(Object(Illuminate\Queue\Events\JobProcessing)) #20 /var/app/current/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(421): Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction->Spatie\Multitenancy\Actions{closure}(Object(Illuminate\Queue\Events\JobProcessing)) #21 /var/app/current/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(249): Illuminate\Events\Dispatcher->Illuminate\Events{closure}('Illuminate\Queu...', Array) #22 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(653): Illuminate\Events\Dispatcher->dispatch('Illuminate\Queu...') #23 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(426): Illuminate\Queue\Worker->raiseBeforeJobEvent('sqs', Object(Illuminate\Queue\Jobs\SqsJob)) #24 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(389): Illuminate\Queue\Worker->process('sqs', Object(Illuminate\Queue\Jobs\SqsJob), Object(Illuminate\Queue\WorkerOptions)) #25 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(176): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\SqsJob), 'sqs', Object(Illuminate\Queue\WorkerOptions)) #26 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(138): Illuminate\Queue\Worker->daemon('sqs', 'mycarpass.fifo', Object(Illuminate\Queue\WorkerOptions)) #27 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(121): Illuminate\Queue\Console\WorkCommand->runWorker('sqs', 'mycarpass.fifo') #28 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle() #29 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container{closure}() #30 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure)) #31 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure)) #32 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/Container.php(662): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL) #33 /var/app/current/vendor/laravel/framework/src/Illuminate/Console/Command.php(208): Illuminate\Container\Container->call(Array) #34 /var/app/current/vendor/symfony/console/Command/Command.php(326): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle)) #35 /var/app/current/vendor/laravel/framework/src/Illuminate/Console/Command.php(178): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle)) #36 /var/app/current/vendor/symfony/console/Application.php(1081): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #37 /var/app/current/vendor/symfony/console/Application.php(320): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #38 /var/app/current/vendor/symfony/console/Application.php(174): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #39 /var/app/current/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(200): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #40 /var/app/current/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #41 {main}

Next Illuminate\Database\QueryException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'db_lgnhs.tenants' doesn't exist (Connection: landlord, SQL: select * from tenants where tenants.id = 3 limit 1) in /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php:795 Stack trace: #0 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(934): Illuminate\Database\Connection->runQueryCallback('select * from ...', Array, Object(Closure)) #1 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(914): Illuminate\Database\Connection->tryAgainIfCausedByLostConnection(Object(Illuminate\Database\QueryException), 'select * from ...', Array, Object(Closure)) #2 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(758): Illuminate\Database\Connection->handleQueryException(Object(Illuminate\Database\QueryException), 'select * from ...', Array, Object(Closure)) #3 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Connection.php(424): Illuminate\Database\Connection->run('select * from ...', Array, Object(Closure)) #4 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2736): Illuminate\Database\Connection->select('select * from `...', Array, true) #5 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2724): Illuminate\Database\Query\Builder->runSelect() #6 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(3278): Illuminate\Database\Query\Builder->Illuminate\Database\Query{closure}() #7 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2725): Illuminate\Database\Query\Builder->onceWithColumns(Array, Object(Closure)) #8 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(717): Illuminate\Database\Query\Builder->get(Array) #9 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(701): Illuminate\Database\Eloquent\Builder->getModels(Array) #10 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php(296): Illuminate\Database\Eloquent\Builder->get(Array) #11 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(443): Illuminate\Database\Eloquent\Builder->first(Array) #12 /var/app/current/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\Database\Eloquent\Builder->find(3) #13 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2335): Illuminate\Database\Eloquent\Model->forwardCallTo(Object(Illuminate\Database\Eloquent\Builder), 'find', Array) #14 /var/app/current/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2347): Illuminate\Database\Eloquent\Model->__call('find', Array) #15 /var/app/current/vendor/spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php(105): Illuminate\Database\Eloquent\Model::__callStatic('find', Array) #16 /var/app/current/vendor/spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php(132): Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction->findTenant(Object(Illuminate\Queue\Events\JobProcessing)) #17 /var/app/current/vendor/spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php(46): Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction->bindOrForgetCurrentTenant(Object(Illuminate\Queue\Events\JobProcessing)) #18 /var/app/current/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(421): Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction->Spatie\Multitenancy\Actions{closure}(Object(Illuminate\Queue\Events\JobProcessing)) #19 /var/app/current/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(249): Illuminate\Events\Dispatcher->Illuminate\Events{closure}('Illuminate\Queu...', Array) #20 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(653): Illuminate\Events\Dispatcher->dispatch('Illuminate\Queu...') #21 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(426): Illuminate\Queue\Worker->raiseBeforeJobEvent('sqs', Object(Illuminate\Queue\Jobs\SqsJob)) #22 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(389): Illuminate\Queue\Worker->process('sqs', Object(Illuminate\Queue\Jobs\SqsJob), Object(Illuminate\Queue\WorkerOptions)) #23 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(176): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\SqsJob), 'sqs', Object(Illuminate\Queue\WorkerOptions)) #24 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(138): Illuminate\Queue\Worker->daemon('sqs', 'mycarpass.fifo', Object(Illuminate\Queue\WorkerOptions)) #25 /var/app/current/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(121): Illuminate\Queue\Console\WorkCommand->runWorker('sqs', 'mycarpass.fifo') #26 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle() #27 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container{closure}() #28 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure)) #29 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure)) #30 /var/app/current/vendor/laravel/framework/src/Illuminate/Container/Container.php(662): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL) #31 /var/app/current/vendor/laravel/framework/src/Illuminate/Console/Command.php(208): Illuminate\Container\Container->call(Array) #32 /var/app/current/vendor/symfony/console/Command/Command.php(326): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle)) #33 /var/app/current/vendor/laravel/framework/src/Illuminate/Console/Command.php(178): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle)) #34 /var/app/current/vendor/symfony/console/Application.php(1081): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #35 /var/app/current/vendor/symfony/console/Application.php(320): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #36 /var/app/current/vendor/symfony/console/Application.php(174): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #37 /var/app/current/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(200): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #38 /var/app/current/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput)) #39 {main}
MattWiseParking commented 10 months ago

@masterix21 i have added the above log for the issue i am currently receiving.

I did make some changes, see below my config/multitenancy.php file

<?php

use Illuminate\Broadcasting\BroadcastEvent;
use Illuminate\Events\CallQueuedListener;
use Illuminate\Mail\SendQueuedMailable;
use Illuminate\Notifications\SendQueuedNotifications;
use Spatie\Multitenancy\Actions\ForgetCurrentTenantAction;
use Spatie\Multitenancy\Actions\MakeQueueTenantAwareAction;
use Spatie\Multitenancy\Actions\MakeTenantCurrentAction;
use Spatie\Multitenancy\Actions\MigrateTenantAction;
use App\Models\Tenant;

return [
    /*
     * This class is responsible for determining which tenant should be current
     * for the given request.
     *
     * This class should extend `Spatie\Multitenancy\TenantFinder\TenantFinder`
     *
     */
    //'tenant_finder' => \Spatie\Multitenancy\TenantFinder\DomainTenantFinder::class,
    'tenant_finder' => \App\Multitenancy\DomainTenantFinder::class,

    /*
     * These fields are used by tenant:artisan command to match one or more tenant
     */
    'tenant_artisan_search_fields' => [
        'id',
    ],

    /*
     * These tasks will be performed when switching tenants.
     *
     * A valid task is any class that implements Spatie\Multitenancy\Tasks\SwitchTenantTask
     */
    'switch_tenant_tasks' => [
        \Spatie\Multitenancy\Tasks\PrefixCacheTask::class,
        \Spatie\Multitenancy\Tasks\SwitchTenantDatabaseTask::class,
        \Spatie\Multitenancy\Tasks\SwitchRouteCacheTask::class,
        \App\Multitenancy\PrefixStorageTask::class,
        \App\Multitenancy\LaravelDailyInvoice::class,
    ],

    /*
     * Prefix - allows you to specify a prefix when creating a new database
     * note this is not apart of the plugin, its used on the tenantObserver
     */
    'prefix' => env('DB_MULTI_PREFIX','db_'),

    /*
     * This class is the model used for storing configuration on tenants.
     *
     * It must be or extend `Spatie\Multitenancy\Models\Tenant::class`
     */
    'tenant_model' => Tenant::class,

    /*
     * If there is a current tenant when dispatching a job, the id of the current tenant
     * will be automatically set on the job. When the job is executed, the set
     * tenant on the job will be made current.
     */
    'queues_are_tenant_aware_by_default' => true,

    /*
     * The connection name to reach the tenant database.
     *
     * Set to `null` to use the default connection.
     */
    'tenant_database_connection_name' => null,

    /*
     * The connection name to reach the landlord database
     */
    'landlord_database_connection_name' => 'landlord',

    /*
     * This key will be used to bind the current tenant in the container.
     */
    'current_tenant_container_key' => 'currentTenant',

    /**
     * Set it to `true` if you like to cache the tenant(s) routes
     * in a shared file using the `SwitchRouteCacheTask`.
     */
    'shared_routes_cache' => true,

    /*
     * You can customize some of the behavior of this package by using your own custom action.
     * Your custom action should always extend the default one.
     */
    'actions' => [
        'make_tenant_current_action' => MakeTenantCurrentAction::class,
        'forget_current_tenant_action' => ForgetCurrentTenantAction::class,
        'make_queue_tenant_aware_action' => MakeQueueTenantAwareAction::class,
        'migrate_tenant' => MigrateTenantAction::class,
    ],

    /*
     * You can customize the way in which the package resolves the queuable to a job.
     *
     * For example, using the package laravel-actions (by Loris Leiva), you can
     * resolve JobDecorator to getAction() like so: JobDecorator::class => 'getAction'
     */
    'queueable_to_job' => [
        SendQueuedMailable::class => 'mailable',
        SendQueuedNotifications::class => 'notification',
        CallQueuedListener::class => 'class',
        BroadcastEvent::class => 'event',
    ],

    /*
     * Jobs tenant aware even if these don't implement the TenantAware interface.
     */
    'tenant_aware_jobs' => [
        \App\Jobs\AddToWhitelistJob::class,
        \App\Jobs\AnprCameraImportJob::class,
        \App\Jobs\ChangedBatchToProcessedJob::class,
        \App\Jobs\PopulateAnprCameraImportVehicleJob::class,
        \App\Jobs\PopulateAnprImportReportsJob::class,
        \App\Jobs\PopulateVehicleDvlaData::class,
        \App\Jobs\ProcessPaygInvoiceJob::class,
        \App\Jobs\RefundInvoice::class,
        \App\Jobs\UpdateStripeCustomerDetails::class,
        \App\Jobs\AddVehicleToUserJob::class,
        \App\Jobs\ProcessAnprFactoryJob::class,
    ],

    /*
     * Jobs not tenant aware even if these don't implement the NotTenantAware interface.
     */
    'not_tenant_aware_jobs' => [
        // ...
    ],
];

The Job Class that is failing:

<?php

namespace App\Jobs;

use App\Anpr\AnprFactory;
use App\Models\CarparkAnprRead;
use App\Models\CarparkCamera;
use App\Models\Tenant;
use App\Models\Vehicle;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
use Spatie\Multitenancy\Jobs\TenantAware;
use Throwable;

class ProcessAnprFactoryJob implements ShouldQueue,TenantAware
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $carparkAnprReadId;

    public $carparkCameraId;

    public $vehicleId;

    public $useTenantId;
    /**
     * Create a new job instance.
     */
    public function __construct($carparkAnprReadId,$carparkCameraId,$vehicleId,$useTenantId)
    {
        $this->carparkAnprReadId = $carparkAnprReadId;
        $this->carparkCameraId = $carparkCameraId;
        $this->vehicleId = $vehicleId;
        $this->useTenantId = $useTenantId;
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        $tenant = Tenant::current();
        if(is_null($tenant)) {
            $tenant = Tenant::find($this->useTenantId);
            $tenant->makeCurrent();
        } elseif(!is_null($tenant) && $tenant->id != $this->useTenantId) {
            Tenant::forgetCurrent();
            $tenant = Tenant::find($this->useTenantId);
            $tenant->makeCurrent();
        }
        $carparkAnprRead = CarparkAnprRead::findOrFail($this->carparkAnprReadId);
        $carparkCamera = CarparkCamera::findOrFail($this->carparkCameraId);
        $vehicle = Vehicle::findOrFail($this->vehicleId);
        activity('ANPR API')->log('the anpr factory job has started');
        $factory = new AnprFactory();
        $factory->process($carparkAnprRead, $carparkCamera,$vehicle);
        activity('ANPR API')->log('the anpr factory job has ended');
    }

    /**
     * Handle a job failure.
     */
    public function failed(Throwable $exception): void
    {
        Log::error('ProcessAnprFactoryJob job failed: '.$exception->getMessage());
        Artisan::call('queue:restart');
    }
}

The client/code that is calling the above job class, i:

ProcessAnprFactoryJob::dispatch($carparkAnprRead->id, $carparkCamera->id, $vehicle->id, $tenantId)->onConnection('sqs');
masterix21 commented 10 months ago

The issue concerns your landlord connection: could you make it default in your .env?

Are you sure that db_lgnhs database contains the table tenants?

MattWiseParking commented 10 months ago

@masterix21 table tenants should only be in the landlord connection database which is set in the .env file initially.

If I make the landlord connection default I receive an error: your tenant_database_connection_name is empty, please make the tenant connection.

If i change the tenant_database_connection_name to tenant then every entry in the tenants table becomes the landlords database.

I think its something to do with the landlord connection which doesn't seem to be setting the database, hence it defaults to the tenant database instead and tries to find the tenants table in the db_lgnhs database.

I dont know if this is the issue, but none of my models are set to use UseTenantsConnection except the Tenant model which I created and extended from the original Tenants model which defaults to useLandlordConnection.

Other than that I am out of ideas.

anotherZero commented 10 months ago

I believe this is the same issue I've been struggling with as well. I have found that my scheduled queued jobs seem to work OK if I keep queuing items at a regular interval. However, if I don't have a job drop onto the queue for ~15 minutes it tends to fail.

Here is the relevant portion of the stack trace found on the failed jobs list in horizon. It indicates that it's trying to search for the tenant but it is using the tenant database when it should be using the landlord connection. The landlord user doesn't have permissions to read the tenant databases, and it's trying to read the landlord_site_info table in the tenant database.

Next Illuminate\Database\QueryException: SQLSTATE[HY000] [1044] Access denied for user 'landlorduser'@'localhost' to database 'tenant' (Connection: landlord, SQL: select * from `landlord_site_info` where `landlord_site_info`.`id` = 6 limit 1) in /var/www/mysite/vendor/laravel/framework/src/Illuminate/Database/Connection.php:822

I'd be happy to provide any additional info that can help get to the bottom of this.

MattWiseParking commented 10 months ago

@anotherZero same here, it happens once a day after nothing sent to the queue for approx 8 hours.

MattWiseParking commented 8 months ago

@masterix21 do you have an update regarding this issue?

masterix21 commented 8 months ago

Hi @MattWiseParking, sorry, but no, because I have no AWS SQS instances.

gssj85 commented 7 months ago

I'm having something similar when job starts the default connection is set to tenant the tenant connection with null host

masterix21 commented 7 months ago

@gssj85, please post your error.

spatie-bot commented 2 months ago

Dear contributor,

because this issue seems to be inactive for quite some time now, I've automatically closed it. If you feel this issue deserves some attention from my human colleagues feel free to reopen it.

MattWiseParking commented 2 months ago

this is still an issue and requires support

Bouhaddi commented 2 months ago

yes same issue here