An extension for running tasks asynchronously via queues.
Documentation is at docs/guide/README.md.
The preferred way to install this extension is through composer.
Either run
php composer.phar require --prefer-dist yiisoft/yii-queue
or add
"yiisoft/yii-queue": "~3.0"
to the require
section of your composer.json
file.
If you have experience with yiisoft/yii2-queue
, you will find out that this package is similar.
Though, there are some key differences which are described in the "migrating from yii2-queue" article.
Each queue task consists of two parts:
- A message is a class implementing
MessageInterface
. For simple cases you can use the default implementation,Yiisoft\Yii\Queue\Message\Message
. For more complex cases you should implement the interface by your own. - A message handler is a callable called by a
Yiisoft\Yii\Queue\Worker\Worker
. The handler handles each queue message.
For example, if you need to download and save a file, your message may look like the following:
$data = [
'url' => $url,
'destinationFile' => $filename,
];
$message = new \Yiisoft\Yii\Queue\Message\Message('file-download', $data);
Then you should push it to the queue:
$queue->push($message);
Its handler may look like the following:
class FileDownloader
{
private string $absolutePath;
public function __construct(string $absolutePath)
{
$this->absolutePath = $absolutePath;
}
public function handle(\Yiisoft\Yii\Queue\Message\MessageInterface $downloadMessage): void
{
$fileName = $downloadMessage->getData()['destinationFile'];
$path = "$this->absolutePath/$fileName";
file_put_contents($path, file_get_contents($downloadMessage->getData()['url']));
}
}
The last thing we should do is to create a configuration for the Yiisoft\Yii\Queue\Worker\Worker
:
$handlers = ['file-download' => [new FileDownloader('/path/to/save/files'), 'handle']];
$worker = new \Yiisoft\Yii\Queue\Worker\Worker(
$handlers, // Here it is
$dispatcher,
$logger,
$injector,
$container
);
There is the way to run all the messages that are already in the queue, and then exit:
$queue->run(); // this will execute all the existing messages
$queue->run(10); // while this will execute only 10 messages as a maximum before exit
If you don't want your script to exit immediately, you can use the listen
method:
$queue->listen();
You can also check the status of a pushed message (the queue driver you are using must support this feature):
$queue->push($message);
$id = $message->getId();
// Get status of the job
$status = $queue->status($id);
// Check whether the job is waiting for execution.
$status->isWaiting();
// Check whether a worker got the job from the queue and executes it.
$status->isReserved();
// Check whether a worker has executed the job.
$status->isDone();
Some of queue drivers support different behaviors like delayed execution and prioritized queues.
Important: Not every driver supports all the behaviors. See concrete driver documentation to find out if
it supports the behavior you want to use. Driver will throw a BehaviorNotSupportedException
if it does not support
some behaviors attached to the message you are trying to push to the queue.
To be sure message will be read from queue not earlier then 5 seconds since it will be pushed to the queue, you can use DelayBehavior
:
$message->attachBehavior(new DelayBehavior(5));
$queue->push($message);
The exact way of task execution depends on the driver used. Most drivers can be run using console commands, which the component automatically registers in your application.
The following command obtains and executes tasks in a loop until the queue is empty:
yii queue/run
The following command launches a daemon which infinitely queries the queue:
yii queue/listen
See the documentation for more details about driver specific console commands and their options.
The component also has the ability to track the status of a job which was pushed into queue.
For more details see the guide.