laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.2k stars 10.89k forks source link

Queue/Jobs: ShouldBeUnique still locks when job could not be dispatched #48483

Closed c-zenker closed 12 months ago

c-zenker commented 12 months ago

Laravel Version

10.24.0

PHP Version

8.2.10

Database Driver & Version

MySQL 8 in docker environment

Description

Hi, we are facing a problem with ShouldBeUnique or ShouldBeUniqueUntilProcessing Jobs that get dispatched to a database queue connection. When the database is not (yet) available, or our containers are facing temporary issues when connecting to the database, the job dispatch fails (as expected). But unexpectedly the locking-mechanism (using e.g. file cache driver) still locks and this job cannot be dispatched anymore, even when the database connection is up again.

Steps To Reproduce

Example Job:

<?php
namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Support\Facades\Cache;

class TestJob implements ShouldQueue, ShouldBeUniqueUntilProcessing
{
    use Dispatchable, Queueable;

    protected string $asdf;

    public function __construct(string $someValue)
    {
        $this->onQueue('default'); // default
        $this->onConnection('database'); // default
        $this->asdf = $someValue;
    }

    public function handle(): void
    {
        \Log::info('Hello World '.$this->asdf);
    }

    public function uniqueId(): string
    {
        return $this->asdf;
    }

    public function uniqueVia(): Repository
    {
        return Cache::driver('file');
    }
}

Example dispatch (via artisan command):

<?php
namespace App\Console\Commands;

use App\Jobs\TestJob;
use Illuminate\Console\Command;

class TmpSth extends Command
{
    protected $signature = 'tmp:sth';

    public function handle(): void
    {
        TestJob::dispatch('myValue')
            ->delay(60);
    }
}

Reproduce

1) Don't start the database (yet) or shut it down 2) php artisan tmp:sth The command fails with a database connection timeout exception, as expected

3) Start database 4) php artisan tmp:sth

Actual behaviour: The command succeeds, but does not try to dispatch the TestJob to the database job queue anymore. The job-queue remains empty. Expected behaviour: The command succeeds and the TestJob got dispatched to the database

driesvints commented 12 months ago

Hey there,

Can you first please try one of the support channels below? If you can actually identify this as a bug, feel free to open up a new issue with a link to the original one and we'll gladly help you out.

Thanks!