как предотвратить одновременное выполнение заданий laravel

#laravel

Вопрос:

У меня есть задание, как показано ниже:

 class ProcessActions implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    protected $user_id;

    public $uniqueFor = 4;

    /**
     * Create a new job instance.
     *
     * @param mixed $action_id
     */
    public function __construct($user_id)
    {
        $this->user_id = $user_id;
    }

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

    /**
     * Handle a job failure.
     */
    public function failed()
    {

    }

    /**
     * Execute the job.
     */
    public function handle()
    {
        Log::debug('');
        Log::debug('Started Time: '.date('Y-m-d H:i:s'));


            try {
            } catch (Exception $e) {
                Log::critical('Error occurred.');
                Log::critical($e);
                

                // make the job failed
                $this->job->fail($e);
            }
    }

    public function middleware()
    {
        return [(new WithoutOverlapping($this->user_id))->releaseAfter(4)->expireAfter(4)];
    }
}
 

Как я должен предотвратить одновременное выполнение заданий? уникальные и без перекрытия не сработали, и у меня есть задания, которые выполняются одновременно.

На самом деле я хочу, чтобы задания с одинаковым идентификатором пользователя выполнялись с задержкой в 4 секунды.

Кроме того, поскольку я проверил jobs’available_at и время, когда я вошел в дескриптор, имеют разницу в несколько секунд.

Комментарии:

1. возможно, вы можете использовать sleep (5) в конце каждого задания с задержкой в 5 секунд

2. Вы можете подумать github.com/spatie/laravel-rate-limited-job-middleware .

Ответ №1:

Вы можете использовать функцию ограничения скорости в laravel

Подробнее об этом можно прочитать здесь — https://laravel.com/docs/8.x/queues#rate-limiting

В вашем классе заданий внутри метода дескриптора добавьте этот код — убедитесь key , что это уникальное значение, вот пример кода

По сути, это ограничивает работника обработкой одного задания для пользователя в данный момент времени.смотрите uuid, следующее задание будет обработано через 4 секунды.

 $uuid='process_action_'.$user_id;
Redis::funnel($uuid)->limit(1)->then(function () {
    //job logic
}, function () {
    
    //reattempt the job after 4 seconds
    return $this->release(4);
});