From ad288542ae5687f8705a55867d69ccd1fb327844 Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sun, 10 Nov 2019 12:34:09 +0300 Subject: [PATCH 1/7] Added MessageRecordingEntity functionality --- .../MessageRecordingEntityInterface.php | 25 +++++++ .../MessageRecordingEntitySubscriber.php | 63 ++++++++++++++++++ .../Messenger/MessageRecordingEntityTrait.php | 39 +++++++++++ .../Tests/Fixtures/MessageRecordingEntity.php | 18 +++++ .../MessageRecordingEntitySubscriberTest.php | 66 +++++++++++++++++++ .../MessageRecordingEntityTraitTest.php | 43 ++++++++++++ 6 files changed, 254 insertions(+) create mode 100644 src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityInterface.php create mode 100644 src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntitySubscriber.php create mode 100644 src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntitySubscriberTest.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php diff --git a/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityInterface.php b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityInterface.php new file mode 100644 index 0000000000000..1b0d37ae5922d --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Messenger; + +/** + * @author Tobias Nyholm + * @author Matthias Noback + * @author Valentin Udaltsov + */ +interface MessageRecordingEntityInterface +{ + /** + * @param callable $dispatcher callable(object[] $messages): void + */ + public function dispatchMessages(callable $dispatcher): void; +} diff --git a/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntitySubscriber.php b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntitySubscriber.php new file mode 100644 index 0000000000000..d509ce779d893 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntitySubscriber.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Messenger; + +use Doctrine\Common\EventSubscriber; +use Doctrine\ORM\Event\PostFlushEventArgs; +use Doctrine\ORM\Events; +use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp; + +/** + * @author Tobias Nyholm + * @author Matthias Noback + * @author Valentin Udaltsov + */ +final class MessageRecordingEntitySubscriber implements EventSubscriber +{ + /** + * @var MessageBusInterface + */ + private $bus; + + public function __construct(MessageBusInterface $bus) + { + $this->bus = $bus; + } + + /** + * {@inheritdoc} + */ + public function getSubscribedEvents(): array + { + return [ + Events::postFlush, + ]; + } + + public function postFlush(PostFlushEventArgs $args): void + { + foreach ($args->getEntityManager()->getUnitOfWork()->getIdentityMap() as $entities) { + foreach ($entities as $entity) { + if (!$entity instanceof MessageRecordingEntityInterface) { + continue; + } + + $entity->dispatchMessages(function (array $messages): void { + foreach ($messages as $message) { + $this->bus->dispatch($message, [new DispatchAfterCurrentBusStamp()]); + } + }); + } + } + } +} diff --git a/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php new file mode 100644 index 0000000000000..c333141de93ef --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Messenger; + +/** + * @author Tobias Nyholm + * @author Matthias Noback + * @author Valentin Udaltsov + */ +trait MessageRecordingEntityTrait +{ + /** + * @var object[] + */ + private $messages = []; + + /** + * @see MessageRecordingEntityInterface::dispatchMessages() + */ + final public function dispatchMessages(callable $dispatcher): void + { + $dispatcher($this->messages); + $this->messages = []; + } + + final protected function recordMessage(object $message): void + { + $this->messages[] = $message; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php new file mode 100644 index 0000000000000..6c269b175f6ad --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php @@ -0,0 +1,18 @@ +recordMessage($message); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntitySubscriberTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntitySubscriberTest.php new file mode 100644 index 0000000000000..c220681df96a5 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntitySubscriberTest.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Messenger; + +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Event\PostFlushEventArgs; +use Doctrine\ORM\UnitOfWork; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\Messenger\MessageRecordingEntitySubscriber; +use Symfony\Bridge\Doctrine\Tests\Fixtures\MessageRecordingEntity; +use Symfony\Component\Messenger\Envelope; +use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp; + +class MessageRecordingEntitySubscriberTest extends TestCase +{ + public function testPostFlush(): void + { + $entity = new MessageRecordingEntity(); + $message1 = new \stdClass(); + $message2 = new \stdClass(); + $message2->a = 1; + $entity->doRecordMessage($message1); + $entity->doRecordMessage($message2); + + $uow = $this->createMock(UnitOfWork::class); + $uow + ->expects(static::once()) + ->method('getIdentityMap') + ->willReturn([[$entity]]) + ; + + $em = $this->createMock(EntityManagerInterface::class); + $em + ->expects(static::once()) + ->method('getUnitOfWork') + ->willReturn($uow) + ; + + $args = new PostFlushEventArgs($em); + + $bus = $this->createMock(MessageBusInterface::class); + $bus + ->expects(static::exactly(2)) + ->method('dispatch') + ->withConsecutive( + [$message1, [new DispatchAfterCurrentBusStamp()]], + [$message2, [new DispatchAfterCurrentBusStamp()]] + ) + ->willReturn(new Envelope(new \stdClass())) + ; + + $subscriber = new MessageRecordingEntitySubscriber($bus); + + $subscriber->postFlush($args); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php new file mode 100644 index 0000000000000..f546502f5f9bd --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Messenger; + +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\Tests\Fixtures\MessageRecordingEntity; + +class MessageRecordingEntityTraitTest extends TestCase +{ + public function testDispatch(): void + { + $entity = new MessageRecordingEntity(); + $message = new \stdClass(); + + $entity->doRecordMessage($message); + + $entity->dispatchMessages(static function (array $messages) use ($message): void { + static::assertSame([$message], $messages); + }); + } + + public function testMessagesClearedAfterDispatch(): void + { + $entity = new MessageRecordingEntity(); + $entity->doRecordMessage(new \stdClass()); + + $entity->dispatchMessages(static function (): void { + }); + + $entity->dispatchMessages(static function (array $messages): void { + static::assertCount(0, $messages); + }); + } +} From acfc5baa4a482668ca6fd167688140f5dd77aeaf Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sun, 10 Nov 2019 12:45:04 +0300 Subject: [PATCH 2/7] Removed strict types in MessageRecordingEntity fixture --- .../Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php index 6c269b175f6ad..e92c63b82781f 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php @@ -1,7 +1,5 @@ Date: Sun, 10 Nov 2019 12:46:10 +0300 Subject: [PATCH 3/7] Added a standard phpdoc header to the MessageRecordingEntity fixture --- .../Doctrine/Tests/Fixtures/MessageRecordingEntity.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php index e92c63b82781f..365c445e94720 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/MessageRecordingEntity.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bridge\Doctrine\Tests\Fixtures; use Symfony\Bridge\Doctrine\Messenger\MessageRecordingEntityInterface; From a704101eb75f5301f261f8b07e20d91f5d7f3aa9 Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sat, 23 Nov 2019 11:33:35 +0100 Subject: [PATCH 4/7] Renamed the subscriber --- ...ber.php => DispatchEntityMessagesDoctrineSubscriber.php} | 2 +- ...php => DispatchEntityMessagesDoctrineSubscriberTest.php} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/Symfony/Bridge/Doctrine/Messenger/{MessageRecordingEntitySubscriber.php => DispatchEntityMessagesDoctrineSubscriber.php} (95%) rename src/Symfony/Bridge/Doctrine/Tests/Messenger/{MessageRecordingEntitySubscriberTest.php => DispatchEntityMessagesDoctrineSubscriberTest.php} (89%) diff --git a/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntitySubscriber.php b/src/Symfony/Bridge/Doctrine/Messenger/DispatchEntityMessagesDoctrineSubscriber.php similarity index 95% rename from src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntitySubscriber.php rename to src/Symfony/Bridge/Doctrine/Messenger/DispatchEntityMessagesDoctrineSubscriber.php index d509ce779d893..79322cbc1611c 100644 --- a/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntitySubscriber.php +++ b/src/Symfony/Bridge/Doctrine/Messenger/DispatchEntityMessagesDoctrineSubscriber.php @@ -22,7 +22,7 @@ * @author Matthias Noback * @author Valentin Udaltsov */ -final class MessageRecordingEntitySubscriber implements EventSubscriber +final class DispatchEntityMessagesDoctrineSubscriber implements EventSubscriber { /** * @var MessageBusInterface diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntitySubscriberTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php similarity index 89% rename from src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntitySubscriberTest.php rename to src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php index c220681df96a5..d2abe5a221419 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntitySubscriberTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php @@ -15,13 +15,13 @@ use Doctrine\ORM\Event\PostFlushEventArgs; use Doctrine\ORM\UnitOfWork; use PHPUnit\Framework\TestCase; -use Symfony\Bridge\Doctrine\Messenger\MessageRecordingEntitySubscriber; +use Symfony\Bridge\Doctrine\Messenger\DispatchEntityMessagesDoctrineSubscriber; use Symfony\Bridge\Doctrine\Tests\Fixtures\MessageRecordingEntity; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp; -class MessageRecordingEntitySubscriberTest extends TestCase +class DispatchEntityMessagesDoctrineSubscriberTest extends TestCase { public function testPostFlush(): void { @@ -59,7 +59,7 @@ public function testPostFlush(): void ->willReturn(new Envelope(new \stdClass())) ; - $subscriber = new MessageRecordingEntitySubscriber($bus); + $subscriber = new DispatchEntityMessagesDoctrineSubscriber($bus); $subscriber->postFlush($args); } From 4a289b573348ff59238abccb3bad7825e9a24c47 Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sat, 23 Nov 2019 15:00:40 +0100 Subject: [PATCH 5/7] Added a hook before the message is dispatched to allow to modify the envelope --- ...spatchEntityMessagesDoctrineSubscriber.php | 16 +++-- .../EntityMessagePreDispatchEvent.php | 41 +++++++++++ ...chEntityMessagesDoctrineSubscriberTest.php | 68 ++++++++++++++----- 3 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/Messenger/EntityMessagePreDispatchEvent.php diff --git a/src/Symfony/Bridge/Doctrine/Messenger/DispatchEntityMessagesDoctrineSubscriber.php b/src/Symfony/Bridge/Doctrine/Messenger/DispatchEntityMessagesDoctrineSubscriber.php index 79322cbc1611c..453515364ba88 100644 --- a/src/Symfony/Bridge/Doctrine/Messenger/DispatchEntityMessagesDoctrineSubscriber.php +++ b/src/Symfony/Bridge/Doctrine/Messenger/DispatchEntityMessagesDoctrineSubscriber.php @@ -14,8 +14,10 @@ use Doctrine\Common\EventSubscriber; use Doctrine\ORM\Event\PostFlushEventArgs; use Doctrine\ORM\Events; +use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** * @author Tobias Nyholm @@ -24,14 +26,13 @@ */ final class DispatchEntityMessagesDoctrineSubscriber implements EventSubscriber { - /** - * @var MessageBusInterface - */ private $bus; + private $dispatcher; - public function __construct(MessageBusInterface $bus) + public function __construct(MessageBusInterface $bus, EventDispatcherInterface $dispatcher) { $this->bus = $bus; + $this->dispatcher = $dispatcher; } /** @@ -52,9 +53,12 @@ public function postFlush(PostFlushEventArgs $args): void continue; } - $entity->dispatchMessages(function (array $messages): void { + $entity->dispatchMessages(function (array $messages) use ($entity): void { foreach ($messages as $message) { - $this->bus->dispatch($message, [new DispatchAfterCurrentBusStamp()]); + $envelope = Envelope::wrap($message, [new DispatchAfterCurrentBusStamp()]); + $event = new EntityMessagePreDispatchEvent($entity, $envelope); + $this->dispatcher->dispatch($event); + $this->bus->dispatch($event->getEnvelope()); } }); } diff --git a/src/Symfony/Bridge/Doctrine/Messenger/EntityMessagePreDispatchEvent.php b/src/Symfony/Bridge/Doctrine/Messenger/EntityMessagePreDispatchEvent.php new file mode 100644 index 0000000000000..0fb26c3a57018 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Messenger/EntityMessagePreDispatchEvent.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Messenger; + +use Symfony\Component\Messenger\Envelope; + +final class EntityMessagePreDispatchEvent +{ + private $entity; + private $envelope; + + public function __construct(object $entity, Envelope $envelope) + { + $this->entity = $entity; + $this->envelope = $envelope; + } + + public function getEntity(): object + { + return $this->entity; + } + + public function getEnvelope(): Envelope + { + return $this->envelope; + } + + public function setEnvelope(Envelope $envelope): void + { + $this->envelope = $envelope; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php index d2abe5a221419..007ea4394cc52 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php @@ -16,14 +16,16 @@ use Doctrine\ORM\UnitOfWork; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\Messenger\DispatchEntityMessagesDoctrineSubscriber; +use Symfony\Bridge\Doctrine\Messenger\EntityMessagePreDispatchEvent; use Symfony\Bridge\Doctrine\Tests\Fixtures\MessageRecordingEntity; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\DispatchAfterCurrentBusStamp; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; class DispatchEntityMessagesDoctrineSubscriberTest extends TestCase { - public function testPostFlush(): void + public function testMessagesAreDispatched(): void { $entity = new MessageRecordingEntity(); $message1 = new \stdClass(); @@ -32,11 +34,56 @@ public function testPostFlush(): void $entity->doRecordMessage($message1); $entity->doRecordMessage($message2); + $bus = $this->createMock(MessageBusInterface::class); + $bus + ->expects(static::exactly(2)) + ->method('dispatch') + ->withConsecutive( + [Envelope::wrap($message1, [new DispatchAfterCurrentBusStamp()])], + [Envelope::wrap($message2, [new DispatchAfterCurrentBusStamp()])], + ) + ->willReturn(new Envelope(new \stdClass())) + ; + + $dispatcher = $this->createMock(EventDispatcherInterface::class); + + $args = $this->createPostFlushArgs([$entity]); + + $subscriber = new DispatchEntityMessagesDoctrineSubscriber($bus, $dispatcher); + $subscriber->postFlush($args); + } + + public function testEventIsDispatched(): void + { + $entity = new MessageRecordingEntity(); + $message = new \stdClass(); + $entity->doRecordMessage($message); + + $bus = $this->createMock(MessageBusInterface::class); + $bus->method('dispatch')->willReturn(new Envelope(new \stdClass())); + + $dispatcher = $this->createMock(EventDispatcherInterface::class); + $dispatcher + ->expects(static::once()) + ->method('dispatch') + ->with(new EntityMessagePreDispatchEvent($entity, Envelope::wrap($message, [ + new DispatchAfterCurrentBusStamp(), + ]))) + ; + + $args = $this->createPostFlushArgs([$entity]); + + $subscriber = new DispatchEntityMessagesDoctrineSubscriber($bus, $dispatcher); + $subscriber->postFlush($args); + } + + private function createPostFlushArgs(array $entities): PostFlushEventArgs + { $uow = $this->createMock(UnitOfWork::class); $uow ->expects(static::once()) ->method('getIdentityMap') - ->willReturn([[$entity]]) + ->willReturn([$entities]) ; $em = $this->createMock(EntityManagerInterface::class); @@ -46,21 +93,6 @@ public function testPostFlush(): void ->willReturn($uow) ; - $args = new PostFlushEventArgs($em); - - $bus = $this->createMock(MessageBusInterface::class); - $bus - ->expects(static::exactly(2)) - ->method('dispatch') - ->withConsecutive( - [$message1, [new DispatchAfterCurrentBusStamp()]], - [$message2, [new DispatchAfterCurrentBusStamp()]] - ) - ->willReturn(new Envelope(new \stdClass())) - ; - - $subscriber = new DispatchEntityMessagesDoctrineSubscriber($bus); - - $subscriber->postFlush($args); + return new PostFlushEventArgs($em); } } From 109fec341efa6c667705939c8cf1ffb2a66cadd4 Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sat, 23 Nov 2019 15:35:55 +0100 Subject: [PATCH 6/7] Fixed the DispatchEntityMessagesDoctrineSubscriberTest --- .../Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php index 007ea4394cc52..002298d4da595 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/DispatchEntityMessagesDoctrineSubscriberTest.php @@ -40,7 +40,7 @@ public function testMessagesAreDispatched(): void ->method('dispatch') ->withConsecutive( [Envelope::wrap($message1, [new DispatchAfterCurrentBusStamp()])], - [Envelope::wrap($message2, [new DispatchAfterCurrentBusStamp()])], + [Envelope::wrap($message2, [new DispatchAfterCurrentBusStamp()])] ) ->willReturn(new Envelope(new \stdClass())) ; From e70edbf370f3b3ea0622e84ea37c3e2de01909ee Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Tue, 3 Dec 2019 01:18:10 +0300 Subject: [PATCH 7/7] Clear messages before calling the dispatcher --- .../Messenger/MessageRecordingEntityTrait.php | 4 ++-- .../MessageRecordingEntityTraitTest.php | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php index c333141de93ef..ab1a2e71695d3 100644 --- a/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php +++ b/src/Symfony/Bridge/Doctrine/Messenger/MessageRecordingEntityTrait.php @@ -28,8 +28,8 @@ trait MessageRecordingEntityTrait */ final public function dispatchMessages(callable $dispatcher): void { - $dispatcher($this->messages); - $this->messages = []; + [$messages, $this->messages] = [$this->messages, []]; + $dispatcher($messages); } final protected function recordMessage(object $message): void diff --git a/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php b/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php index f546502f5f9bd..5ebffe3540633 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Messenger/MessageRecordingEntityTraitTest.php @@ -40,4 +40,21 @@ public function testMessagesClearedAfterDispatch(): void static::assertCount(0, $messages); }); } + + public function testMessagesClearedOnDispatchFailure(): void + { + $entity = new MessageRecordingEntity(); + $entity->doRecordMessage(new \stdClass()); + + try { + $entity->dispatchMessages(static function (): void { + throw new \Exception(); + }); + } catch (\Exception $exception) { + } + + $entity->dispatchMessages(static function (array $messages): void { + static::assertCount(0, $messages); + }); + } }