@kategg

Как сохранить очередность выполнения заданий в очереди?

Есть проблема с порядком обработки заданий в очереди. Допустим, что я, с интервалом 2-3 секунды, занесла в очередь 3 задания.
Первое задание выполняется 30 секунд и записывает в лог цифру 1
public function handle()
    {
        sleep(30);
        file_put_contents(storage_path('/logs/journal.log'), 1, FILE_APPEND);
    }

второе - выполняется 20 секунд и записывает цифру 2
public function handle()
    {
        sleep(10);
        file_put_contents(storage_path('/logs/journal.log'), 2, FILE_APPEND);
    }

третье - выполняется 2 секунды и записывает цифру 3
public function handle()
    {
        sleep(2);
        file_put_contents(storage_path('/logs/journal.log'), 3, FILE_APPEND);
    }


В итоге, если запустить несколько воркеров, то в журнале я увижу запись - 321, а надо получить 123. Вопрос, как сохранить очередность выполнения заданий, чтобы задания, которые были добавлены позднее, но имеют меньшее время выполнения, не опережали предыдущие?
  • Вопрос задан
  • 153 просмотра
Пригласить эксперта
Ответы на вопрос 2
JhaoDa
@JhaoDa
LaravelRUS Team
Надо начать читать документацию и не изобретать велосипедов с БД и прочим.
Ответ написан
RusPOPsy
@RusPOPsy
Говорила мама, учи математику ...
Ну раз chain не устраивает, то есть в доке и другой раздел: "Предотвращение дублирования работы"
#preventing-job-overlaps

Надо сделать примерно такой trait:
<?php
namespace App\Jobs;

use Illuminate\Queue\Middleware\WithoutOverlapping;

trait WithoutOverlappingFileWrite
{

    public function middleware(): array
    {
        return [
            (new WithoutOverlapping('file_write'))
                ->shared() // https://laravel.com/docs/11.x/queues#sharing-lock-keys
        ];
    }

    public function retryUntil(): \Illuminate\Support\Carbon
    {
        return now()->addSeconds(60);
    }

}


и use WithoutOverlappingFileWrite; во всех Job'ах
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы