Laravel FIFO queue with Redis

Laravel FIFO queue with Redis

Recently I needed to create a FIFO (First In, First Out) queue in Laravel to run specific actions inside a long-running worker from outside the worker itself. I had two possibilities:

  1. Database, creating a table, but I had also to create a Model, Service, Repository and many other things;

  2. Redis, already installed.

Of course, I went with Redis, taking advantage of two main commands: RPUSH and LPOP.

Theory

The first one, RPUSH, will append an item to a given list (and create if it does not exist) and will be responsible for pushing new items to the list; LPOP, instead, will pop out the first item in the list, deleting it from our "queue". A quick visual explanation:

Code

Thanks to Laravel Redis facade we can use the Redis commands as static methods and, because LPOP will return false if the list is empty, we can easily loop until there are no more items to process:

<?php

use Illuminate\Support\Facades\Redis;

// Define our queue name
$queueName = 'fifo';

// Put some items in our queue
// You can run this code outside your long-running worker
Redis::rpush($queueName, 'item1');
Redis::rpush($queueName, 'item2');


// ---------------------- somewhere else ----------------------

// Process until there are no more elements
// Note that will close when the queue is empty
while ($item = Redis::lpop($queueName)) {
    echo 'Found: ' . $item . PHP_EOL;
}

// Output:
// "Found: item1"
// "Found: item2"

If you want to run it in a long-running worker, you'll need to slightly change the while loop into something like this (or using a library like the great ReactPHP) to not stop the script even if the queue is empty:

<?php

use Illuminate\Support\Facades\Redis;

// Define our queue name
$queueName = 'fifo';

// Process until there are no more elements
while (true) {
    if ($item = Redis::lpop($queueName)) {
        echo 'Found: ' . $item . PHP_EOL;
    }
}

// Output:
// "Found: item1"
// "Found: item2"