feature #31282 [Messenger] Add WorkerStoppedEvent (chalasr)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Messenger] Add WorkerStoppedEvent

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

In 4.2, one was able to decorate a transport and hook into `TransportInterface::stop()` to perform some business tasks when the `messenger:consume` process gets killed.
In 4.3 the `stop()` logic has been moved to `Worker` which cannot be decorated when used via `messenger:consume`.
This PR adds a marker event dispatched when the worker is stopped to provide the same capability.

Briefly discussed with @weaverryan.
My use case:
I have a temporary CSV file locally which grows while consuming jobs.
This file is uploaded to AWS S3 and squashed once a while (every 5minutes). It is also uploaded when the `messenger:consume` process gets stopped (to store the remaining lines).
For the former (time-based upload), I can listen on `WorkflowMessageHandledEvent` to make the upload happens in case the 5 minutes delay is elapsed. This solves the latter.

Commits
-------

0e7898b622 [Messenger] Add WorkerStoppedEvent
This commit is contained in:
Samuel ROZE 2019-04-28 14:59:42 +01:00
commit 96a7907979
4 changed files with 34 additions and 4 deletions

View File

@ -4,6 +4,7 @@ CHANGELOG
4.3.0
-----
* Added `WorkerStoppedEvent` dispatched when a worker is stopped.
* Added optional `MessageCountAwareInterface` that receivers can implement
to give information about how many messages are waiting to be processed.
* [BC BREAK] The `Envelope::__construct()` signature changed:

View File

@ -0,0 +1,23 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Messenger\Event;
/**
* Dispatched when a worker has been stopped.
*
* @author Robin Chalas <robin.chalas@gmail.com>
*
* @experimental in 4.3
*/
class WorkerStoppedEvent
{
}

View File

@ -16,6 +16,7 @@ use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
use Symfony\Component\Messenger\Event\WorkerStoppedEvent;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Retry\RetryStrategyInterface;
@ -187,11 +188,12 @@ class WorkerTest extends TestCase
$eventDispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$eventDispatcher->expects($this->exactly(2))
$eventDispatcher->expects($this->exactly(3))
->method('dispatch')
->withConsecutive(
[$this->isInstanceOf(WorkerMessageReceivedEvent::class)],
[$this->isInstanceOf(WorkerMessageHandledEvent::class)]
[$this->isInstanceOf(WorkerMessageHandledEvent::class)],
[$this->isInstanceOf(WorkerStoppedEvent::class)]
);
$worker = new Worker([$receiver], $bus, [], $eventDispatcher);
@ -214,11 +216,12 @@ class WorkerTest extends TestCase
$eventDispatcher = $this->getMockBuilder(EventDispatcherInterface::class)->getMock();
$eventDispatcher->expects($this->exactly(2))
$eventDispatcher->expects($this->exactly(3))
->method('dispatch')
->withConsecutive(
[$this->isInstanceOf(WorkerMessageReceivedEvent::class)],
[$this->isInstanceOf(WorkerMessageFailedEvent::class)]
[$this->isInstanceOf(WorkerMessageFailedEvent::class)],
[$this->isInstanceOf(WorkerStoppedEvent::class)]
);
$worker = new Worker([$receiver], $bus, [], $eventDispatcher);

View File

@ -15,6 +15,7 @@ use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
use Symfony\Component\Messenger\Event\WorkerStoppedEvent;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\Exception\LogicException;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
@ -109,6 +110,8 @@ class Worker implements WorkerInterface
usleep($options['sleep']);
}
}
$this->dispatchEvent(new WorkerStoppedEvent());
}
private function handleMessage(Envelope $envelope, ReceiverInterface $receiver, string $receiverName, ?RetryStrategyInterface $retryStrategy)