Working with queues in concrete5

A queue can be rather useful when you want to process a lot of data, but also when I just want to make sure things react quickly. Let’s have a look at a simple case where you might want to send an email.

In a lot of cases people send e-mails right in a controller action. This is okay for a lot of sites, but sometimes if things are mission critical it helps to use a queue. Imagine what happens if there’s a temporary problem with the mail system, since you’re sending it right in your controller you’ll probably show the user an error message telling him that something went wrong. Seeing errors is hardly ever a good thing, with a queue you could use a simple operation to put the action in a queue and process it later. If it fails you could try again a bit later and if it fails permanently put it in a log file you’re monitoring.

There might also be a maintenance task that you can finish before PHP times out. Using a queue would make it more solid, put every object you want to process in a queue and process it piece by piece.

Putting things in the queue

It’s fairly simple to put things the queue. All you need is a queue name to ensure you can keep your tasks apart and the data you need later to process the item from the queue:

use Concrete\Core\Foundation\Queue\Queue;
 
$queue = Queue::get('queue-demo');
$queue->send(1);

With this we are putting the number 1 in a queue called “queue-demo”. Now that we have objects in our queue we need to process them.

Processing queue

When processing a queue we obviously have to use the same queue name.

use Concrete\Core\Foundation\Queue\Queue;
 
$queue = Queue::get('queue-demo');
$queueMessages = $queue->receive(10);
foreach ($queueMessages as $msg) {
   $userId = $msg->body;
   // load the object for the user ID and process it
 
   $queue->deleteMessage($msg);
}

That’s basically all you need to do, but you’ll of course need to put that code somewhere.

concrete5 has an easy to extend CLI API. You derive a class from “Symfony\Component\Console\Command\Command”, implement the “execute” method and handle your queue there. Once you register your command, you can access it by running “./concrete/bin/concrete5”
You can find a complete example here: https://github.com/Remo/concrete5-queue-demo. Here are some of the relevant lines:

You’ll just have to run your command regularly to execute it, a cronjob like this should do the trick: “./concrete/bin/concrete5 queue-demo:process-notifications”.

There’s also a way to handle everything in a job which is especially useful for maintenance tasks as it doesn’t require that you add queue items initiaited by a user action. There’s a good article in the official documentation about this: https://documentation.concrete5.org/developers/jobs/creating-and-scheduling-a-queueable-job.

Benefits

  • Non-blocking executing of tasks
  • Avoid timeouts when handling a lot of data

Disadvantages

  • Adds a bit more complexity to your code
  • concrete5 queues require polling on the executing side, adding a delay to your task. Deosn’t apply to queues in general, if you use something like beanstalk you can process tasks immediately

Some of the code was written by Michele Locati. Hope you enjoy working with queues!




No Comments


You can leave the first : )



Leave a Reply

Your email address will not be published. Required fields are marked *