Queue API в Drupal 7

Главные вкладки

Аватар пользователя InternetDevels.com InternetDevels.com 18 января 2013 в 17:11


Queue API — специальный функционал в Drupal, который позволяет формировать очередь и контролировать выполнение трудоемких операций на сайте. В отличии от Batch API, Queue API полностью автоматизирует жизнь вашего сайта.

Полная статья »

Комментарии

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 18 января 2013 в 17:40

Полезно.

«
В отличии от Batch API, Queue API полностью автоматизирует жизнь вашего сайта.
»

«
Обратите внимание на то, что выполнение операции длится 10 секунд, если функция через 10 секунд не будет выполнена тогда Queue снова ее запустить через тоже самое время.
»

Получается, если у нас в очереди 100 элементов и на 99 закончилось отведённое время, то очередь запуститься снова сначала? Тогда это фигня а не полная автоматизация

Аватар пользователя tibezh tibezh 18 января 2013 в 17:52

>>> Получается, если у нас в очереди 100 элементов и на 99 закончилось отведённое время, то очередь запуститься снова сначала? Тогда это фигня а не полная автоматизация

Здесь Вы уже хозяин, как напишите функционал, так и будет.

Элементарный пример:

у нас есть 100 материалов со статусом "не опубликовано", на Queue нужно сделать все материалы опубликованными.
Если вы будете на операции просто пересохранять материал с изменением статуса, тогда да, операция у вас может крутится вечность, если она не справляется за отведенное время.
Но если, вы будете делать проверку в материале типа "ЕСЛИ материал == неопубликованный ТОГДА изменят статус", тогда эта проверка не будет обновлять все подряд материалы, а только те, которые еще не обновились.

Аватар пользователя Crea Crea 18 января 2013 в 22:29

Queue позволяет распределить работу между N "рабочих", сокращая выполнение всей операции (грубо) в N раз. Queue знает, какие задачи не были выполнены и автоматически их попробует выполнить снова.
Batch для 1 рабочего, и не знает ничего о невыполненных задачах.

В общем, предназначение у них совсем разное.

Аватар пользователя volodymyr volodymyr 21 января 2013 в 16:28

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

Аватар пользователя InternetDevels.com InternetDevels.com 29 апреля 2013 в 12:02

volodymyr wrote:
можете подробнее написать как настроить elysia_cron, а то после установки модуля (elysia_cron) крон не запускается вообще (( только вручную, но если вручную запускать то цикл начинается сначала.
смотрел настойки модуля (elysia_cron) в админке значения есть когда запускать крон.

В модуле elysia_cron есть файлик INSTALL.txt. Скорее всего Вы забыли заменить стандартный друпаловский файлик cron.php на тот файл cron.php что лежит вместе с модулем elysia_cron.

Аватар пользователя roman-yrv roman-yrv 26 апреля 2013 в 21:00

Решил поразбираться с этим и уже возникли следующие вопросы по коду

function internetdevels_queue_select_content($count) {
  static $start;
  if (empty($start)) {
    $start = 0;
  }
  $nodes = array();
  // Choosing nodes older than 1 week.
  $query = db_select('node', 'n')
    ->condition('n.changed', REQUEST_TIME - ((3600 * 24) * 7), '<')
    ->fields('n', array('nid'))
    ->range($start, $count)
    ->orderBy('n.changed', 'ASC')
    ->execute();
  while ($value = $query->fetchAssoc()) {
    $nodes[] = $value['nid'];
  }
  // If we have such material then send the nodes to the Queue.
  if (count($nodes) !== 0) {
    $start += $count;
    $queue = DrupalQueue::get('internetdevels_main_queue');
    // Return number of queues.
    $count = $queue->numberOfItems();
    $queue->createQueue();
    // Sending array with nodes.
    $queue->createItem($nodes);
    // Set the interval 5 minutes.
    $queue->claimItem($start + (60 * 5));
    internetdevels_queue_select_content($count);
  }
  else {
    return;
  }
}

1. Не совсем понятна данная конструкция.
Если $queue уже получена с помощью DrupalQueue::get, то для чего нужно создавать очередь командой $queue->createQueue(); ?
Как-то нелогично, на мой взгляд, что ли ...
Или так просто решили разработчики, да и всё ?

$queue = DrupalQueue::get('internetdevels_main_queue');
    // Return number of queues.
    $count = $queue->numberOfItems();
    $queue->createQueue();
    // Sending array with nodes.
    $queue->createItem($nodes);

2. Не совсем понятно, что выполняется этой командой.
Или выполнение такое: если за 5 минут элемент очереди не обработается, то этот элемент будет обрабатываться повторно ?

$queue->claimItem($start + (60 * 5));

3. С чем связано использование рекурсии ? C тем, что просто так решили разработчики или есть какие-то объективные причины ?

    internetdevels_queue_select_content($count);
Аватар пользователя InternetDevels.com InternetDevels.com 29 апреля 2013 в 12:29

"roman-yrv" wrote:
Решил поразбираться с этим и уже возникли следующие вопросы по коду
1. Не совсем понятна данная конструкция.

Здесь все просто, метод "get" объекта "DrupalQueue" возвращает нам очередь по имени (первый аргумент в методе), а метод "createQueue" Добавляет элемент в очередь и сохраняет его.
Ссылки на документация про метод get и про метод createItem.

"roman-yrv" wrote:
2. Не совсем понятно, что выполняется этой командой.
Или выполнение такое: если за 5 минут элемент очереди не обработается, то этот элемент будет обрабатываться повторно ?

Да все правильно, "если за 5 минут элемент очереди не обработается, то этот элемент будет обрабатываться повторно".

"roman-yrv" wrote:
С чем связано использование рекурсии ? C тем, что просто так решили разработчики или есть какие-то объективные причины ?

Так решили разработчики.

Аватар пользователя roman-yrv roman-yrv 29 апреля 2013 в 14:37

"InternetDevels.com" wrote:
Здесь все просто, метод "get" объекта "DrupalQueue" возвращает нам очередь по имени (первый аргумент в методе), а метод "createQueue" Добавляет элемент в очередь и сохраняет его.
Ссылки на документация про метод get и про метод createItem.

Насчет метода createItem - всё понятно, этот метод добавляет элемент в очередь.
А вот зачем в Вашем случае используется createQueue ? Ведь, по идее, очередь уже получена по имени методом get и содержит всю информацию.
Тем более, я смотрел в коде system.queue.inc, так там методы createQueue не содержат никакого кода.

Или createQueue будет просто пересоздавать очередь в случае, если метод get не сработал ?
Но в Вашем примере createQueue запускается в любом случае ...

Аватар пользователя solo solo 19 января 2014 в 7:43

А в чем может быть проблема, если в очередь добавляется 8 тысяч заданий, а обрабатывается только 6 тысяч? То есть я в начала ф-ции обработки добавляю запись в таблицу лога, и по окончании процесса вижу, что 2 тысячи заданий просто не обрабатываются

Аватар пользователя InternetDevels.com InternetDevels.com 24 января 2014 в 16:44

«А в чем может быть проблема, если в очередь добавляется 8 тысяч заданий, а обрабатывается только 6 тысяч? То есть я в начала ф-ции обработки добавляю запись в таблицу лога, и по окончании процесса вижу, что 2 тысячи заданий просто не обрабатываются»

Здравствуйте!

1. Для начала нужно убедится в том, что в очередь попадают именно эти 8 тыс. записей. Для этого посмотрите в табличку queue, там должны сохранятся эти очереди. Там должна быть очередь именно на Ваших 8 тыс. заданий. Если задания легкие, тогда можно поместить все в одну очередь, соответственно, в табличке queue будет одна запись. Но все же, рекомендуем обработку операций раскинуть на несколько очередей.

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

3. Также посмотрите, нет ли ошибок в таблице лога, например фатал ерроры, они вполне могут быть препятствием к выполнению очереди до конца.