How to lock the job during execution in Laravel?

Viewed 240

I see withoutOverlapping() mutex for commands, but I don't see it for jobs. How can I protect jobs of the same type from overlapping each other?

Thanks!

1 Answers

I think it's possible using the following: https://laravel.com/docs/8.x/queues#unique-jobs

You can specify a needed key that you can pass to the job to mark its uniqueness. In my case, I need to limit requests to a third-party API that happens in the job so if I have more than one worker handling the queue, it's possible to get 429 from the API. As soon as I have many API-keys (per user of the app), I can use it to have the same type of job being exxecuted independently across the app users but lock the job execution if the current job with a specific key is not completed.

Like this:

    //In the class defining you must use ShouldBeUnique interface
    class UpdateSpreadsheet implements ShouldQueue, ShouldBeUnique
    
    //some other code
        
    public function __construct($keyValue)
    {
    //some other constructor code if needed
    $this->keyValue= $keyValue;
    }

    //This function allows to set the unique key
    public function uniqueId()
    {
        return $this->keyValue;
    }

    //If you don't need to wait until the job is processed, you may also specify
    //the time for the force lock removing (so you'll be able to queue another 
    //job with this key after 10 seconds even if the current job is
    //still in process)
    
    public $uniqueFor = 10;
Related