hook_civicrm_QueueRun¶
Summary¶
Fire hook_civicrm_queueRun_{$runner}.
Description¶
This event only fires if these conditions are met:
- The
$queuehas been persisted incivicrm_queue. - The
$queuehas arunnerproperty. - The
$queuehas some pending tasks. - The system has a queue-running agent.
Queue-items executed in this hook can have any (serializable) data-type, and you can receive multiple queue-items in a single batch.
If your queue-items are based on CRM_Queue_Task, then you do not need to implement this hook. You can rely on the standard implementation of hook_civicrm_queueRun_task.
Definition¶
hook_civicrm_queueRun_RUNNER(CRM_Queue_Queue $queue, array $items, &$outcomes)
Parameters¶
-
CRM_Queue_Queue $queueQueue which had the item(s).
-
array $itemsList of claimed items which we may evaluate.
The number of items may vary based on the configuration and data. If the
Queuehasbatch_limit=1(default), then you will only receive one item. But ifbatch_limitis higher, then you may receive multiple items. -
array &$outcomesThe outcomes of each task. Each outcome should be 'ok', 'retry', or 'fail'.
Keys should match the keys in $items.
Availability¶
hook_civicrm_queueRun_{$runner}: CiviCRM v5.51+CRM_Queue_BasicHandlerTrait: CiviCRM v6.1+
Example¶
Create a queue and set the runner property, e.g.
$queue = Civi::queue('my-queue', [
'type' => 'Sql',
'runner' => 'my_stuff',
'batch_limit' => 1,
...
]);
$queue->createItem(/* serializable data #1*/);
$queue->createItem(/* serializable data #2*/);
$queue->createItem(/* serializable data #3*/);
Whenever items are detected in my-queue, the background agent will fire hook_civicrm_queueRun_my_stuff.
To listen to this hook, use the helper BasicHandlerTrait:
/**
* @service civi.queue.my_stuff
*/
class MyHandler extends AutoService implements EventSubscriberInterface {
use CRM_Queue_BasicHandlerTrait;
public static function getSubscribedEvents() {
return ['&hook_civicrm_queueRun_my_stuff' => 'runBatch'];
}
protected function runItem($item, \CRM_Queue_Queue $queue): void {
print_r(["Received item:" => $item));a
// If this function ends normally, then we consider the $item successful.
// If this function encounters a recoverable error, then we check the $queue configuration
// to decide what to do next (e.g. retry, abort, delete, etc).
// If this function abends (PHP fatal, power-outage, etc), then any pending items in the
// batch (incl $item and its successors) will be retried later.
}
// Optionally, pre-validate items before executing them.
// protected function validateItem($item): bool {}
// Optionally, make a loggable summary of the
// protected function getItemDetails($item): array {}
}
Note that the hook calls our pre-existing/inherited method (runBatch()). We must implement runItem() for the main logic, and we can (optionally) implement methods like validateItem().
Of course, you don't need to use BasicHandlerTrait. You can implement the hook directly, as in this minimal example:
function myextension_civicrm_queueRun_my_stuff(CRM_Queue_Queue $queue, array $items, array &$outcomes): void {
foreach ($items as $key => $item) {
$outcomes[$key] = /* do something with $item and get outcome */;
}
}
This looks simpler at first, but it omits a lot of details about batched error handling. You need to identify errors, map them
back to specific tasks, decide how to report the error, and decide what to do with other/remaining tasks. This may be
necessary and worthy in some cases -- for example, if your logic really runs faster as a batched operation, or if you
integrate with some external API that has its own error protocols. But in general, the BasicHandlerTrait::runItem()
is easier to implement.