Using php-resque with Laravel

Jessie O’Brien wrote a great blog post¬†explaining how he’d got php-resque setup with Laravel. I won’t rehash the background on php-resque or Laravel but instead I wanted to post because I did the exact same thing last week, but I went about it in a different way.

To begin, I ported the core of the php-resque run script (Resque.php) into an artisan task. This allows to run artisan which gives you the full laravel environment, but still run the php-resque workers. So to run the queue, it’s as simple as running

php artisan resque <queue> <logLevel> <interval> <pidFile> 
/**
 * A Laravel Task which runs the PHP-Resque worker
 * This should be run using Artisan (php artisan resque) which will 
 * then kick off a php-resque worker and listen for incoming messages 
 * coming into the redis queues.
 */
class Resque_Task
{
    /**
     * @param $arguments
     */
    public function run($arguments)
    {
        Bundle::start('php-resque');

        $queue    = array_get($arguments, 0, 'default');
        $logLevel = array_get($arguments, 1, 0);
        $interval = array_get($arguments, 2, 5);
        $pidFile  = array_get($arguments, 3);

        $redis_config = Config::get("database.redis.default");
        $backend      = $redis_config['host'] . ':' . $redis_config['port'];

        // Connect to Redis
        Resque::setBackend($backend);

        $queues           = explode(',', $queue);
        $worker           = new Resque_Worker($queues);
        $worker->logLevel = $logLevel;

        if ($pidFile) {
            file_put_contents($pidFile, getmypid()) or 
              die('Could not write PID information to ' . $pidFile);
        }

        fwrite(STDOUT, '*** Starting worker ' . $worker . "\n");

        $worker->work($interval);
    }
}

The next piece I wanted, was to be able to write each of the tasks which I execute on the queue as simple artisan tasks. That way I could test them in isolation and run them independantly of the queue just using artisan.

All I needed to do was create a simple php-resque Job which could run any artisan Task.

/**
 * A PHP-Resque Job which starts a Laravel Task.
 * This enables us to use PHP-Resque as robust processing queue
 * but still use Laravel Commands, bundles etc to do the work
 *
 */
class Laravel_Job
{
    public function setUp()
    {
    }

    public function perform()
    {
        $task      = array_get($this->args, 'task');
        $arguments = array_get($this->args, 'arguments');

        Command::run(array($task, $arguments));
    }

    public function tearDown()
    {
    }
}

So, that’s it. If I wanted to run a long-running artisan task, I can simply issue the following command (perhaps from one of my controllers in response to a user action).

Resque::enqueue('queue', 'Laravel_Job', array('task => 'LongRunningLaravelTask', 'arguments' => 'some param'), true);
05
Dec 2012
POSTED BY
POSTED IN Laravel PHP
DISCUSSION 7 Comments