То, что я хотел бы сделать, - это отправить задание, а затем продолжить отправку того же задания после завершения предыдущего, чтобы было непрерывное l oop отправляемого задания. Как указано в первом варианте, ранее он работал с драйвером очереди базы данных.
Теперь я использую Redis, чтобы мне было легче отслеживать свои работы через Horizon.
Чтобы запустить первое задание, я использую пользовательскую команду ремесленника, но это также может быть сделано из контроллера, это всего лишь первая отправка.
My config/horizon
(local
config совпадает с production
):
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['arbitrage'],
'balance' => 'auto',
'processes' => 2,
'tries' => 1,
],
'supervisor-2' => [
'connection' => 'redis',
'queue' => ['trade'],
'balance' => 'auto',
'processes' => 4,
'tries' => 1,
],
'supervisor-3' => [
'connection' => 'redis',
'queue' => ['balance', 'trade_meta'],
'balance' => 'auto',
'processes' => 5,
'tries' => 1,
],
'supervisor-4' => [
'connection' => 'redis',
'queue' => ['notifications'],
'balance' => 'auto',
'processes' => 2,
'tries' => 1,
],
],
Вариант 1: отправить новое задание в конце задания
По окончании задания handle()
Я пересылаю его так, чтобы он работал непрерывно.
Это на самом деле работало нормально (процесс выполнялся неделями подряд) при использовании драйвера базы данных.
Задание:
class ArbitrageJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1;
public $timeout = 30;
// Process things here
ArbitrageJob::dispatch()->onQueue('arbitrage');
}
Вариант 2: отправить новое задание с помощью Queue:after
Задание:
class ArbitrageJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1;
public $timeout = 30;
}
Затем в AppServiceProvider:
Queue::after(function (JobProcessed $event) {
ProcessArbitrage::dispatch()->onQueue('arbitrage');
});
То, что я вижу сейчас для обоих вариантов, так это то, что при каждом запуске происходит увеличение памяти (я регистрирую это через memory_get_usage(true)
).
Первый запуск - 28 МБ, следующий - 32 МБ, и он продолжает увеличиваться до 122 МБ, а затем я получаю следующую ошибку: Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\ArbitrageJob has been attempted too many times or run too long. The job may have previously timed out.
Вероятно, связано: в config/horizon
Я установил memory_limit
на 768 МБ, но похоже, что он выходит из строя намного раньше. Или это потому, что он ограничивает объем памяти до 128 МБ на одного работника?