Spiral provides support for background PHP processing and a queue system. This feature is available out of the box and allows you to work with a variety of message brokers.
Make sure to add Spiral\Queue\Bootloader\QueueBootloader
to your application kernel.
public function defineBootloaders(): array
{
return [
// ...
\Spiral\Queue\Bootloader\QueueBootloader::class,
// ...
];
}
Read more about bootloaders in the Framework — Bootloaders section.
The default queue configuration can be found in the app/config/queue.php
file. This configuration file includes a set
of options for each queue driver as well as aliases, which allow you to specify a default queue driver for your
application to use.
return [
/** Default queue connection name */
'default' => env('QUEUE_CONNECTION', 'sync'),
/** Aliases for queue connections, if you want to use domain specific queues */
'aliases' => [
// 'mailQueue' => 'null',
// 'ratingQueue' => 'sync',
],
'connections' => [
'sync' => [
// Job will be handled immediately without queueing
'driver' => 'sync',
],
'null' => [
// Do nothing
'driver' => 'null',
],
],
'registry' => [
'handlers' => [
'sample::job' => App\Jobs\SampleJob::class
],
'serializers' => [
ObjectJob::class => 'json',
]
],
'driverAliases' => [
'sync' => \Spiral\Queue\Driver\SyncDriver::class,
'null' => \Spiral\Queue\Driver\NullDriver::class,
],
];
To create a new queue connection in your application, you can add a new section to the connections
section of the
queue
configuration file.
Queue aliasing is a feature that allows your application and modules to access the queue system in a variety of ways, using separate connections that are related to a single physical queue.
return [
'aliases' => [
'mailQueue' => 'roadrunner',
'ratingQueue' => 'sync',
],
];
To obtain a queue instance by its name or alias, you can use the getConnection
method of the
Spiral\Queue\QueueConnectionProviderInterface
. This method takes a string argument representing the name of the
desired queue connection, and returns an instance of the Spiral\Queue\QueueInterface
.
For example, if you want to get a queue instance for a name or alias called mailQueue
, you could use the
following code:
use Spiral\Queue\QueueConnectionProviderInterface;
$container->bind(MyService::class, function(QueueConnectionProviderInterface $provider) {
return new MyService($provider->getConnection('mailQueue'));
})
final class MyService
{
public function __construct(
private readonly QueueInterface $queue
) {
}
}
You can register handlers for your job classes to associate which handler should be handled for a specific job.
'registry' => [
'handlers' => [
'sample::job' => App\Jobs\SampleJob::class
],
],
If the available queue driver does not meet your specific needs, you can create your own custom driver by implementing
the Spiral\Queue\QueueInterface
interface.
Here is an example implementation of a fake queue driver:
namespace App\Infrastructure\Queue;
use Spiral\Queue\SerializerRegistryInterface;
use Spiral\Queue\QueueInterface;
final class RedisQueue implements QueueInterface
{
public function __construct(
private readonly SerializerRegistryInterface $redis,
private readonly Redis $redis,
private readonly string $server,
private readonly string $queueName,
) {
}
public function push(string $name, array $payload = [], OptionsInterface $options = null): string
{
$payload = $this->serializerRegistry->getSerializer($name)->serialize($payload);
$id = // generate job id
// Push job to the redis broker and return job id
$this->redis->...
return $id;
}
}
Once you have defined your custom driver, you can register it in the configuration file:
'connections' => [
'mail' => [
'driver' => \App\Infrastructure\Queue\RedisQueue::class,
'server' => 'redis://localhost:6379',
'queueName' => 'mail',
],
],
So when you use the mail
connection in your application, Spiral IoC container will create an instance of the
RedisQueue
class and pass the redis://localhost:6379
and mail
values for the $server
and $queueName
parameters, respectively.
You can also register your driver as an alias in the driverAliases
section of the queue configuration file.
'driverAliases' => [
'redis' => \App\Infrastructure\Queue\RedisQueue::class,
// ...
],
Or register a driver alias via Bootloader:
namespace App\Application\Bootloader;
use Spiral\Boot\Bootloader\Bootloader;
use App\Infrastructure\Queue\RedisQueue;
use Spiral\Queue\Bootloader\QueueBootloader;
class AppBootloader extends Bootloader
{
public function init(QueueBootloader $queue): void
{
$queue->registerDriverAlias(RedisQueue::class, 'redis');
}
}
See more
Read more about job handler in the Queue — Running Jobs section.