I'm looking to implement the queue API via some hook_cron() call.

This page is a good example of my current understanding of how to implement this: http://www.leveltendesign.com/blog/randall-knutson/cron-queues-processin...

Where I implement two hooks (hook_cron and hook_cron_queue_info). hook_cron_queue_info includes a reference to a worker callback function, whose only argument is the data from the queue item.

A few questions:

1. Does the worker callback only work on createItem() calls within hook_cron?
2. What happens to the queue item after processing? Does it get deleted, or does it act only as if the item was claimed and released?

Ultimately, what I want is to be able to add items to the queue ad hoc and only have the processing of the items take place in the cron run. Relatedly, I'd want the ability to just release a queue item selectively during processing (rather than deleting it) based on data within the queue item's data. It appears as though neither of these are really possible the way things are.

Any advice on the above would be greatly appreciated.

Thanks in advance!

Comments

iamEAP’s picture

Answering my own question a few days later... This may prove useful to someone in the future. I will also try and update the documentation regarding queues as it's currently pretty abysmal.

In the various examples I've seen around the web, you'll see people implement:

hook_cron()
hook_cron_queue_info()
arbitrary_worker_callback_function($item)

I got the impression that you had to "register" the queue in hook_cron in order for the queue to be processed on cron runs. This is actually untrue. You only need to implement hook_cron if you are creating/populating your queue on cron. If your queue is pre-populated (through some other means elsewhere), then all you have to implement is hook_cron_queue_info(). Any queue you define and return in this hook will be processed on a cron run regardless of what you have in your hook_cron, if anything at all.

As such, if you have conditions on how often your queue should be processed in cron (i.e. if cron is set to run every twenty minutes, but you only want the queue processed every hour), then you'd add those conditions in hook_cron_queue_info(). (So you're conditionally adding queues to the returned array.) For example:

function YOURMODULE_cron_queue_info()
{
  $queues = array();
  if(date('G')==2)
  {
    $queues['YOURQUEUE'] = array('
      'worker callback' => 'YOURMODULE_worker_callback',
      'time' => 15,
    );
  }
  return $queues;
}

function YOURMODULE_worker_callback($item)
{
  // process your queue item here
}

The code above will only process the queue YOURQUEUE when cron is run at 2:00am.

To be explicit, after an item is processed via YOURMODULE_worker_callback($item), the item is deleted from the queue. I'm still not certain if this functionality can be overridden (e.g. by extending/implementing your own queue), but that is the current functionality.

hawkeye.twolf’s picture

If you don't want your item to be deleted, you have two options: Just re-add it to the queue at the end of your worker callback (creates a new item at the end of your queue) or throw an exception (leaves the original item in the queue).

Hawkeye Tenderwolf
a Senior Developer
at Lullabot

ruloweb’s picture

If you throw an exception, the expire data will be different than 0 so claimItem wont retreive it any more. I think creating the item again is the way to go.

EDIT
My bad, system_cron will reset all queue items and set their expire to 0 :)

ruloweb

jcmiller09’s picture

Just wanted to put this out there if anyone else was using the worker callback as I have...

If your worker callback has a return value, it seems to keep the item in the queue as if it threw an exception. Even returning TRUE seems to keep the API from deleting the items, and sets the expiration column back to 0. I was piggybacking on a function that is used elsewhere by other modules, and thus it was returning a value. I added some logic to avoid a return value when the function was being used by queue/cron.