Queue API — специальный функционал в Drupal, который позволяет формировать на сайте очередь из трудоемких операций, а также, контролировать их выполнение. В отличии от Batch API, Queue API полностью автоматизирует жизнь вашего сайта.
Queue API использует так называемую атомарную операцию (это такие операции, которые выполняются либо как единое целое, либо не выполняются вовсе).
Представим себе следующий сценарий:
Мы разработали интернет-магазин, в котором пользователи ежедневно делают заказы. Нам нужно отсылать уже обработанную статистику по заказам на некий внешний сервер. Статистику можно обрабатывать и после каждого создаваемого заказа, отсылая данные затем на другой сервер. Но, выполнение таких операций для каждого получаемого заказа - нагрузка непомерная как для нашего сервера, так и для отдаленного.
Тут то нам и пригодится Queue API. С помощью данного инструмента, мы сможем настроить сервер так, чтобы обработка заказов выполнялась в ночное время, именно тогда, когда пользователей на сайте почти нет, и ресурса сервера, где расположен наш интернет-магазин будет вполне достаточно для обработки и закачки всех заказов. В результате мы получаем сайт с автоматизированной (и оптимизированной(!!!)) системой формирования и отправки отчетов.
Перво наперво, нам нужно "сформировать очередь", то есть составить список операций, выполняемых нашей Queue. Для этого нужно написать функцию, которая будет все это формировать при запуске крона. Крон мы будем использовать, поскольку исполнение запроса в БД - операция по ресурсам малозатратная. В коде я буду вести простую обработку материалов, и буду выбирать материалы старше 1 недели, а на Queue операции буду менять дату обновления материала на текущею.
В примере вы видите использование hook_cronapi, который будет доступен после установки модуля elysia_cron. Здесь я выбираю все материалы сайта, и записываю каждые 20 материалов в очередь для Queue. При этом заметьте: модуль Elysia cron по дефолту будет запускать операции каждый час, эту опцию можно убрать в настройках модуля.
Сам хук:
/**
* Implements hook_cronapi().
*/
function internetdevels_queue_cronapi($op, $job = NULL) {
$items = array();
$items['internetdevels_queue_main'] = array(
'description' => 'Send nid to Queue',
'rule' => '0 23 * * *',
'arguments' => array(20),
'callback' => 'internetdevels_queue_select_content',
);
return $items;
}
Функция выполнения крона:
/**
* Cron function.
*/
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;
}
}
