queue
queue copied to clipboard
Trunk enhancements branch
Includes:
- https://github.com/yiisoft/queue/pull/189
- https://github.com/yiisoft/queue/pull/188
- https://github.com/yiisoft/queue/pull/182
Differences:
- Queue messages dispatches through
Psr\EventDispatcherInterface
-
SynchronousAdapter
triggers on both console and web request end events instead of__destruct()
method - No more
PushDispatcher
,ConsomeDispatcher
,FailureDispatcher
and tens of related classes - Eliminated
HandlerEnvelope
How to handle messages now:
- Create
app/config/common/queue.php
file - Write the following:
<?php declare(strict_types=1); use App\Queue\HelloMessage; use App\Queue\HelloMessageHandler; use Yiisoft\Queue\Message\EnvelopeInterface; use Yiisoft\Queue\Message\Message; /** @var array $params */ return [ HelloMessage::class => [ fn(HelloMessage $message, HelloMessageHandler $handler) => $handler->handle($message), ], Message::class => [ fn(Message $message) => $message instanceof EnvelopeInterface ? $message->getMessage() : $message, ], ];
- The keys are Messages to listen. Each message must implement
\Yiisoft\Queue\Message\MessageInterface
.\Yiisoft\Queue\Message\MessageTrait
may help with it - Values are callables, or simply, handlers, like the
yiisoft/event-dispatcher
ones
There are HelloeMessage
itself:
<?php
declare(strict_types=1);
namespace App\Queue;
use Yiisoft\Queue\Message\MessageInterface;
use Yiisoft\Queue\Message\MessageTrait;
class HelloMessage implements MessageInterface
{
use MessageTrait;
public function __construct(
private mixed $message
) {
$this->data = $message;
}
}
And it's handler:
<?php
declare(strict_types=1);
namespace App\Queue;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Queue\Message\MessageHandlerInterface;
use Yiisoft\Queue\Message\MessageInterface;
class HelloMessageHandler implements MessageHandlerInterface
{
public function __construct(private Aliases $aliases)
{
}
public function handle(MessageInterface $message): void
{
file_put_contents(
$this->aliases->get('@runtime/hello-queue.log'),
json_encode($message->getData()) . PHP_EOL,
FILE_APPEND
);
}
}
Now you can use the queue as a regular service in any services or controllers:
<?php
declare(strict_types=1);
namespace App\User\Controller;
use App\Queue\HelloMessage;
use App\Queue\PassMiddleware;
use HttpSoft\Response\TextResponse;
use Yiisoft\Queue\Middleware\MessageHandlerInterface;
use Yiisoft\Queue\Middleware\MiddlewareInterface;
use Yiisoft\Queue\Middleware\Request;
use Yiisoft\Queue\QueueInterface;
class TestController
{
public function index(QueueInterface $queue): TextResponse
{
$queue->push(
new HelloMessage('Hello, World!'), // the message gonna be written in the file in the HelloMessageHandler
new class () implements MiddlewareInterface {
public function process(Request $request, MessageHandlerInterface $handler): Request
{
return $handler->handle($request); // just to be sure all middlewares still work
}
}
);
return new TextResponse('Hello, World!');
}
}
After a \Yiisoft\Yii\Http\Event\AfterRequest
event is thrown application event dispatcher can trigger SynchronousAdapter::run()
and it process all in-memory
messages.
SynchronousAdapter
does double un- and serialization to apply all envelopes to the final message. So SynchronousAdapter
stores serialized with \Yiisoft\Queue\Message\MessageSerializerInterface
, currently it's \Yiisoft\Queue\Message\JsonMessageSerializer
.
When it starts to handles the stored messages it decodes the ones with the same \Yiisoft\Queue\Message\MessageSerializerInterface
and applies all envelopes before it goes to the final queue message handler.