4

I'm trying to dispatch a job which implements shouldBeUnique but it doesn't work, my job is never in the queue. If I remove ShouldBeUnique, it works as expected.

I am using Redis.

Do you guys have an idea what's happening?

Here is my code :

<?php

namespace App\Jobs;

use Exception;
use Throwable;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Foundation\Bus\Dispatchable;

class VerifyJob implements ShouldQueue, ShouldBeUnique
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $releaseDelay = 10;
    public $tries = 3;

    public $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function uniqueId()
    {
        return $this->user->id;
    }

    public function handle()
    {
        \Log::debug('verify 0');

        return;
    }

    public function failed(Throwable $exception)
    {
        \Log::debug('verify 999');
    }
}

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
DimZ
  • 297
  • 4
  • 18
  • 5
    I would guess there's already a job in the queue. https://laravel.com/docs/8.x/queues#unique-job-locks "Behind the scenes, when a ShouldBeUnique job is dispatched, Laravel attempts to acquire a lock with the uniqueId key. If the lock is not acquired, the job is not dispatched." Try changing your `uniqueId` function to set a *different* unique ID (add a random string, for example) and see if it dispatches. – ceejayoz Mar 15 '21 at 11:00
  • 1
    you can set the time for it to be unique public $uniqueFor = 3600; – Basharmal Mar 15 '21 at 11:19
  • There is no job in the queue. I do `php artisan horizon:clear` to remove all jobs in the queue. EDIT: I updated the `uniqueId` and it worked. Why? Of course I have failed jobs etc, but it seems we can dispatch again an event right after it's been completed, isn't it? – DimZ Mar 15 '21 at 12:09
  • Thanks to [ceejayoz](https://stackoverflow.com/questions/66636630/job-with-shouldbeunique-never-dispatched#comment117796052_66636630), I have to use another uniqueId. Why, I don't know but it worked. – DimZ Mar 15 '21 at 12:19

1 Answers1

4

It's because laravel failed to unlock the unique id, and that is why it was able to dispatch again after you use another unique id.

the reason is the file laravel uses to store the unique id doesn't have right permissions. laravel needs to delete it to unlock the id. It's under the storage/framework/cache/data diretory

leungxd
  • 486
  • 4
  • 6
  • 2
    After hours of frustration, it was the cache stored in the location you specified. I managed to resolve this with: php artisan cache:clear – Alex Coetzee Jun 20 '22 at 20:51