Рабочие задания в Laravel обрабатываются сразу же с задержкой

В настоящее время я разрабатываю свое личное приложение, посвященное частным серверам (например, Minecraft Servers), и поскольку запрос на сервер занимает некоторое время, я решил реализовать задания в очереди, однако они не работают должным образом, они запускаются немедленно, когда даже несмотря на то, что они задерживаются, вызывая массовую задержку в запросе страницы.

Здесь мой индекс HomeController(), который вызывает задание для обновления каждого сервера с задержкой в ​​30 секунд:

public function index()
{
    $servers = Server::all();

    foreach($servers as $server)
    {
       //Job Dispatch
       $job = (new UpdateServer($server->id))->delay(30);
       $this->dispatch($job);
    }
    return view('serverlist.index', compact('servers'));
}

Класс задания, который обновляет серверы, следующий:

class UpdateServer extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    protected $id;

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

    public function handle(){
       $server = Server::findOrFail($this->id);

       //preparing the packet
       $test = new RAGBuffer();
       $test->addChar('255');
       $test->addChar('1');
       $test->addShort(1 | 8);

       //finding the server
       $serverGame = new RAGServer($server->server_ip);

       //Get server info
       $status = $serverGame->sendPacket($test);

       $server->onlinePlayers = $status->getOnline();
       $server->peakPlayers = $status->getPeak();
       $server->maxPlayers = $status->getMax();

       if (!$server->save()) {
           //error ocurred
       }
   }
}

Всякий раз, когда запускается индекс HomeController index(), наблюдается серьезная задержка в запросе страницы, я следил за учебником на официальной веб-странице Laravel, пытался найти ответы и ничего.

Итак, что я делаю неправильно? Почему работа не задерживается на 30 секунд, а затем делает это в фоновом режиме на моем сервере? Заранее благодарю вас.

Также: дескриптор() выполняет то, что он должен, он запрашивает сервер, отправляет пакеты и обновляет мою базу данных с правильной информацией.

Ответы

Ответ 1

Вам нужно настроить драйвер очереди, который вы хотите использовать в корневом каталоге dir .env проекта.

По умолчанию драйвер очереди sync, который выполняет именно то, что вы описываете, выполняя очереди немедленно.

Вы можете выбрать несколько разных драйверов очереди, таких как beanstalked или redis (что было бы моим выбором). Там отличная халява на laracasts.com о создании очереди с beanstalked.

Чтобы просмотреть все доступные параметры драйвера очереди в laravel, посмотрите здесь.

Здесь пример .env

APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync      //< put the desired driver here

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

Ответ 2

Для тех, кто сделал изменения выше и все еще не работал, проверьте значение по умолчанию для файла очереди следующим образом: dd(Config::get('queue.default'))

Для меня это не изменилось, пока не сброс кеш-конфигурации:

php artisan config:clear

Ответ 3

Это сводило меня с ума на века, прежде чем я понял, что Laravel 5.7 переименовал QUEUE_DRIVER в QUEUE_CONNECTION в файлах .env

Ответ 4

Если вы работаете на php artisan serve, перезапустите его и снова запустите php artisan serve. Это работало для меня после нескольких часов, пытаясь понять, что это было. :)

Ответ 5

Чтобы проверить локально, вы можете установить драйвер на

QUEUE_DRIVER=database 

и запустите очередь php artisan: таблица а затем php artisan migrate, чтобы получить вашу очередь, сохраненную в db, чтобы вы визуально могли использовать то, что происходит.

и для запуска ваших очередей просто запустить очередь php artisan: прослушать.. и оставить его запущенным, как вы это делаете с помощью artisan serve

Ответ 6

Убедитесь, что

'default' => env('QUEUE_DRIVER', 'database'), 

в config/queue.php и

QUEUE_DRIVER=database 

в .env файле для обеспечения использования драйвера базы данных

Ответ 7

Если вы запускаете тесты для службы очереди через phpunit, убедитесь, что

<env name="QUEUE_DRIVER" value="X"/>

в phpunit.xml не переопределяет нужный драйвер очереди.

Ответ 8

Даже если вы все настроили правильно, это все равно может произойти. У нас была эта проблема с Laravel 5.4, где мы создали много заданий, некоторые из которых были отложены, и добавили их в очередь через Queue:bulk($jobs). Этот вызов, а также Queue::push($job) полностью игнорируют delay и вызывают немедленную обработку задания.

Если вы хотите, чтобы ваша работа была помещена в очередь во время ее настройки, вы должны вызвать dispatch($job).

Ответ 9

Это потому, что функция задержки принимает абсолютную дату в будущем

UpdateServer::dispatch($server->id)->delay(now()->addSeconds(30))