diff --git a/docs/framework/queues/index.md b/docs/framework/queues/index.md index cbc266509033b41f518d15c4c656068efd52231d..4efd43132d814a7558b47a616d18bce4fe55e23f 100644 --- a/docs/framework/queues/index.md +++ b/docs/framework/queues/index.md @@ -55,25 +55,62 @@ $task = $queue->createItem(new CRM_Queue_Task( The callback will receive a `CRM_Queue_TaskContext` object which has 2 properties: the queue object, and a `CRM_Core_Error_Log` (under `log`). This means that it's possible for a task to add more tasks to the queue. By default items are added to the end of the queue. However, you can use the *weight* property to change this, e.g. if the main queue has a default 'weight' of zero, you can add queue items before the next items by setting a lower weight, e.g. -1. +Queue tasks can also specify a specific release time which allows for delayed queue jobs. + +Example + +```php +/** + * Save an action into a queue for delayed processing + * + * @param \DateTime $delayTo + * @param CRM_Civirules_ActionEngine_AbstractActionEngine $actionEngine + */ +public static function delayAction(DateTime $delayTo, CRM_Civirules_ActionEngine_AbstractActionEngine $actionEngine) { + $queue = CRM_Queue_Service::singleton()->create(array( + 'type' => 'Civirules', + 'name' => self::QUEUE_NAME, + 'reset' => false, //do not flush queue upon creation + )); + + //create a task with the action and eventData as parameters + $task = new CRM_Queue_Task( + array('CRM_Civirules_Engine', 'executeDelayedAction'), //call back method + array($actionEngine) //parameters + ); + + //save the task with a delay + $dao = new CRM_Queue_DAO_QueueItem(); + $dao->queue_name = $queue->getName(); + $dao->submit_time = CRM_Utils_Time::getTime('YmdHis'); + $dao->data = serialize($task); + $dao->weight = 0; //weight, normal priority + $dao->release_time = $delayTo->format('YmdHis'); + $dao->save(); +} +``` + ## 3. Run the queue -CiviCRM's `CRM_Queue_Runner` provides two methods: +CiviCRM's `CRM_Queue_Runner` provides three methods: 1. `runAllViaWeb()` This sends the browser to a page with a progress bar on it. Ajax requests are used to trigger each job. 2. `runAll()` This runs all the tasks one after another in one go. -This runner can optionally call a callback and issue a redirect to the browser on completion. By default the runner will stop the queue (and 'release' the current item) in the case of failure, but you can override that so that failed jobs are just deleted and processing contintues with the next item. +3. `runNext()` - This runs the next task in the queue list + +This runner can optionally call a callback and issue a redirect to the browser on completion. By default the runner will stop the queue (and 'release' the current item) in the case of failure, but you can override that so that failed jobs are just deleted and processing continues with the next item. Example: ```php $runner = new CRM_Queue_Runner([ - 'title' => ts('Demo Queue Runner'), - 'queue' => $queue, - 'onEnd' => ['CRM_Demoqueue_Page_DemoQueue', 'onEnd'], - 'onEndUrl' => CRM_Utils_System::url('civicrm/demo-queue/done'), - ]); + 'title' => ts('Demo Queue Runner'), + 'queue' => $queue, + 'onEnd' => ['CRM_Demoqueue_Page_DemoQueue', 'onEnd'], + 'onEndUrl' => CRM_Utils_System::url('civicrm/demo-queue/done'), +]); // If this is a page: $runner->runAllViaWeb(); // does not return @@ -81,6 +118,32 @@ $runner->runAllViaWeb(); // does not return // Otherwise: $runner->runAll(); ``` +Example 2 Running a queue via a cron job or API method style mechanism + +```php +function civicrm_api_job_runspecificqueue($params) { + $returnValues = array(); + + $queue = CRM_Demoqueue_Helper::singleton()->getQueue(); + $runner = new CRM_Queue_Runner([ + 'title' => ts('Demo Queue Runner'), + 'queue' => $queue, + 'errorMode' => CRM_Queue_Runner::ERROR_CONTINUE, + ]); + + $maxRunTime = time() + 30; //stop executing next item after 30 seconds + $continue = TRUE; + + while(time() < $maxRunTime && $continue) { + $result = $runner->runNext(false); + if (!$result['is_continue']) { + $continue = false; //all items in the queue are processed + } + $returnValues[] = $result; + } + // Spec: civicrm_api3_create_success($values = 1, $params = array(), $entity = NULL, $action = NULL) + return civicrm_api3_create_success($returnValues, $params, 'Demoqueue', 'Run'); +``` !!!warning Server configuration has a big impact on how successfully queues will run. Read on!