Пример выполнения очереди my_queue
в drush команде my-module:my-command
:
class MyModuleDrushCommands extends DrushCommands {
/**
* @command my-module:my-command
*/
public function myCommand(): void {
$this->runQueue('my_queue');
}
/**
* Run queue.
*/
protected function runQueue(string $queue_name, int $ping_interval = 10): void {
$queue = \Drupal::queue($queue_name);
$start_timestamp = time();
$date_formatter = \Drupal::service('date.formatter');
$this->io()->text("Выполнение очереди $queue_name ({$queue->numberOfItems()})...");
$queue->garbageCollection();
while ($item = $queue->claimItem()) {
$queue->releaseItem($item);
$process = Drush::drush(Drush::aliasManager()->getSelf(), 'queue:run', [$queue_name], ['time-limit' => $ping_interval]);
$process
->setTimeout(NULL)
->setIdleTimeout(NULL)
->start($process->showRealtime());
$process->wait();
}
$this->io()->text("Очередь $queue_name выполнена за {$date_formatter->formatDiff($start_timestamp, time())}");
}
}
Очередь выполняется по частям, каждая часть в своём подпроцессе, чтобы не упереться в лимиты сервера.
Вместо while ($queue->numberOfItems())
используется while ($item = $queue->claimItem())
+ $queue->releaseItem($item)
, потому что numberOfItems()
возвращает число всех элементов в очереди, включая тех, что уже в работе (например в параллельном процессе) или отложенных (например уже обработаны, но с ошибкой), что может привести к бесконечному циклу.
Написанное актуально для
Drush 11
Похожие записи
- Пример модуля для импорта товаров в Drupal Commerce 2
- Выполнить очередь с помощью Batch API
- Вставка в CKEditor видео из ВКонтакте и Rutube (расширение модуля CKEditor 5 Media Embed)
- Как из PhpStorm выполнить тест(ы)
- Как работает опция "Aggregation type" в настройках полей Views при включённой агрегации
Комментарии
Жду статью про параллельность исполнения)
Добавить комментарий