Skip to content

Instantly share code, notes, and snippets.

@h-collector
Last active November 1, 2023 16:32
Show Gist options
  • Save h-collector/626c1035a0ddffef28fce4b3bc247e70 to your computer and use it in GitHub Desktop.
Save h-collector/626c1035a0ddffef28fce4b3bc247e70 to your computer and use it in GitHub Desktop.
Standalone Laravel Queue + Redis example
{
"name": "h-collector/queue",
"require": {
"illuminate/queue": "^5.2",
"illuminate/redis": "^5.2",
"illuminate/encryption": "^5.2",
"illuminate/bus": "^5.2"
},
"autoload": {
"psr-4": {
"Jobs\\": "Jobs/"
}
},
"authors": [
{
"name": "h-collector",
"email": "[email protected]"
}
]
}
<?php
namespace Jobs;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Redis\Database as Redis;
class Foo extends Job
{
use InteractsWithQueue;
protected $list;
protected $data;
public function __construct($list, $data)
{
$this->list = $list;
$this->data = $data;
}
/**
* Execute the job.
*
* @return void
*/
public function handle(Redis $redis)
{
// sleep for 10 seconds, just as example
sleep(10);
$redis->lpush($this->list, sprintf(
$this->data['format'],
$this->data['task']
));
}
/**
* Handle a job failure.
*
* @return void
*/
public function failed()
{
// Called when the job is failing...
}
}
// https://laravel.com/docs/5.2/queues
// composer install
// configure queue if needed
// start some workers
$ php worker.php
// start master
$ php master.php
<?php
namespace Jobs;
use Illuminate\Bus\Queueable;
abstract class Job
{
/*
|--------------------------------------------------------------------------
| Queueable Jobs
|--------------------------------------------------------------------------
|
| This job base class provides a central location to place any logic that
| is shared across all of your jobs. The trait included with the class
| provides access to the "onQueue" and "delay" queue helper methods.
|
*/
use Queueable;
}
<?php require 'vendor/autoload.php';
use Jobs\Foo;
use Illuminate\Redis\Database as Redis;
// get configured queue
$queue = require __DIR__ . '/queue.php';
// how many tasks
$todo = 6;
$loop = 0;
$list = 'foo:result';
// start up option, reset storage
$redis = $queue->getContainer()[Redis::class];
$redis->ltrim($list, 1, 0);
// make some jobs
foreach (range(1, $todo) as $task) {
$queue->push(new Foo($list, [
'format' => 'The job is done! Task No. %d',
'task' => $task,
]));
}
// some event loop
while ($todo) {
printf("Loop: %d\n", ++$loop);
// check for done jobs
if ($result = $redis->rpop($list)) {
printf("Job done (remaining: %d), result: %s\n", --$todo, $result);
}
// do something else
sleep(1);
}
echo "All done\n";
<?php
use Illuminate\Bus\Dispatcher;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\Factory as QueueFactory;
use Illuminate\Encryption\Encrypter;
use Illuminate\Queue\Capsule\Manager as Queue;
use Illuminate\Queue\Connectors\RedisConnector;
use Illuminate\Redis\Database as Redis;
$queue = new Queue;
$app = $queue->getContainer();
$manager = $queue->getQueueManager();
$queue->addConnection([
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'expire' => 60,
]);
$app->singleton(Redis::class, function () {
return new Redis([
'cluster' => false,
'default' => [
'host' => '127.0.0.1',
'port' => 6379,
'database' => 0,
],
]);
});
$manager->addConnector('redis', function () use ($app) {
return new RedisConnector(
$app[Redis::class]
);
});
$app->singleton('encrypter', function () {
return new Encrypter('blahfkso;lkfoles');
});
$app->singleton(Dispatcher::class, function ($app) {
return new Dispatcher($app, function ($connection = null) use ($app) {
return $app[QueueFactory::class]->connection($connection);
});
});
$app->alias(
'Illuminate\Bus\Dispatcher',
'Illuminate\Contracts\Bus\Dispatcher'
);
$app->alias(
'Illuminate\Bus\Dispatcher',
'Illuminate\Contracts\Bus\QueueingDispatcher'
);
// resolve Container to instance
// $app->instance(Container::class, $app);
$queue->setAsGlobal();
return $queue;
<?php require 'vendor/autoload.php';
use Illuminate\Queue\Worker;
use Illuminate\Queue\Failed\NullFailedJobProvider;
$queue = require __DIR__ . '/queue.php';
$failer = new NullFailedJobProvider;
$worker = new Worker($queue->getQueueManager(), $failer);
$connection = 'default';
$queue = null;
$delay = 0;
$sleep = 1;
$maxTries = 3;
// $worker->daemon($connection);
while (true) {
try {
$result = $worker->pop($connection, $queue, $delay, $sleep, $maxTries);
// Job processed
if ($result['job']) {
printf(
"Job processed: %s, result: %s\n",
$result['job']->getJobId(),
$result['failed'] ? 'Failed' : 'Success'
);
}
} catch (Exception $e) {
echo $e->getTraceAsString();
} catch (Throwable $e) {
echo $e->getTraceAsString();
}
}
@cocochepeau
Copy link

cocochepeau commented Apr 8, 2018

Hey thanks for sharing. Quick question: does this still apply for 5.5 / 5.6? Have you tested it?

@xemose
Copy link

xemose commented Jun 24, 2018

Getting the error

PHP Fatal error:  Uncaught Error: Call to undefined method Illuminate\Container\Container::isDownForMaintenance()

any solutions? Doing the following doesn't seem to work anymore.

<?php
use Illuminate\Container\Container as IlluminateContainer;

class Container extends IlluminateContainer
{
  public function isDownForMaintenance() {
    return false;
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment