Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dd70b10

Browse files
committed
[Scheduler] add failure event
1 parent 934aea0 commit dd70b10

File tree

6 files changed

+101
-15
lines changed

6 files changed

+101
-15
lines changed

src/Symfony/Component/Scheduler/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CHANGELOG
1515
* Add `MessageProviderInterface` to trigger unique messages at runtime
1616
* Add `PreRunEvent` and `PostRunEvent` events
1717
* Add `DispatchSchedulerEventListener`
18+
* Add `FailureEvent` event
1819

1920
6.3
2021
---
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Scheduler\Event;
13+
14+
use Symfony\Component\Scheduler\Generator\MessageContext;
15+
use Symfony\Component\Scheduler\ScheduleProviderInterface;
16+
17+
class FailureEvent
18+
{
19+
public function __construct(
20+
private readonly ScheduleProviderInterface $schedule,
21+
private readonly MessageContext $messageContext,
22+
private readonly object $message,
23+
private readonly \Throwable $error,
24+
) {
25+
}
26+
27+
public function getMessageContext(): MessageContext
28+
{
29+
return $this->messageContext;
30+
}
31+
32+
public function getSchedule(): ScheduleProviderInterface
33+
{
34+
return $this->schedule;
35+
}
36+
37+
public function getMessage(): object
38+
{
39+
return $this->message;
40+
}
41+
42+
public function getError(): \Throwable
43+
{
44+
return $this->error;
45+
}
46+
}

src/Symfony/Component/Scheduler/EventListener/DispatchSchedulerEventListener.php

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@
1414
use Psr\Container\ContainerInterface;
1515
use Psr\EventDispatcher\EventDispatcherInterface;
1616
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17+
use Symfony\Component\Messenger\Envelope;
18+
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
1719
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
1820
use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
21+
use Symfony\Component\Messenger\Stamp\StampInterface;
22+
use Symfony\Component\Scheduler\Event\FailureEvent;
1923
use Symfony\Component\Scheduler\Event\PostRunEvent;
2024
use Symfony\Component\Scheduler\Event\PreRunEvent;
2125
use Symfony\Component\Scheduler\Messenger\ScheduledStamp;
@@ -31,11 +35,8 @@ public function __construct(
3135
public function onMessageHandled(WorkerMessageHandledEvent $event): void
3236
{
3337
$envelope = $event->getEnvelope();
34-
if (!$scheduledStamp = $envelope->last(ScheduledStamp::class)) {
35-
return;
36-
}
3738

38-
if (!$this->scheduleProviderLocator->has($scheduledStamp->messageContext->name)) {
39+
if (!$scheduledStamp = $this->getScheduledStamp($envelope)) {
3940
return;
4041
}
4142

@@ -46,11 +47,7 @@ public function onMessageReceived(WorkerMessageReceivedEvent $event): void
4647
{
4748
$envelope = $event->getEnvelope();
4849

49-
if (!$scheduledStamp = $envelope->last(ScheduledStamp::class)) {
50-
return;
51-
}
52-
53-
if (!$this->scheduleProviderLocator->has($scheduledStamp->messageContext->name)) {
50+
if (!$scheduledStamp = $this->getScheduledStamp($envelope)) {
5451
return;
5552
}
5653

@@ -63,11 +60,36 @@ public function onMessageReceived(WorkerMessageReceivedEvent $event): void
6360
}
6461
}
6562

63+
public function onMessageFailed(WorkerMessageFailedEvent $event): void
64+
{
65+
$envelope = $event->getEnvelope();
66+
67+
if (!$scheduledStamp = $this->getScheduledStamp($envelope)) {
68+
return;
69+
}
70+
71+
$this->eventDispatcher->dispatch(new FailureEvent($this->scheduleProviderLocator->get($scheduledStamp->messageContext->name), $scheduledStamp->messageContext, $envelope->getMessage(), $event->getThrowable()));
72+
}
73+
74+
private function getScheduledStamp(Envelope $envelope): ?StampInterface
75+
{
76+
if (!$scheduledStamp = $envelope->last(ScheduledStamp::class)) {
77+
return null;
78+
}
79+
80+
if (!$this->scheduleProviderLocator->has($scheduledStamp->messageContext->name)) {
81+
return null;
82+
}
83+
84+
return $scheduledStamp;
85+
}
86+
6687
public static function getSubscribedEvents(): array
6788
{
6889
return [
6990
WorkerMessageReceivedEvent::class => ['onMessageReceived'],
7091
WorkerMessageHandledEvent::class => ['onMessageHandled'],
92+
WorkerMessageFailedEvent::class => ['onMessageFailed'],
7193
];
7294
}
7395
}

src/Symfony/Component/Scheduler/Schedule.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1515
use Symfony\Component\Lock\LockInterface;
16+
use Symfony\Component\Scheduler\Event\FailureEvent;
1617
use Symfony\Component\Scheduler\Event\PostRunEvent;
1718
use Symfony\Component\Scheduler\Event\PreRunEvent;
1819
use Symfony\Component\Scheduler\Exception\LogicException;
@@ -152,6 +153,13 @@ public function after(callable $listener, int $priority = 0): static
152153
return $this;
153154
}
154155

156+
public function onFailure(callable $listener, int $priority = 0): static
157+
{
158+
$this->dispatcher->addListener(FailureEvent::class, $listener, $priority);
159+
160+
return $this;
161+
}
162+
155163
public function shouldRestart(): bool
156164
{
157165
return $this->shouldRestart;

src/Symfony/Component/Scheduler/Scheduler.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Psr\EventDispatcher\EventDispatcherInterface;
1515
use Symfony\Component\Clock\Clock;
1616
use Symfony\Component\Clock\ClockInterface;
17+
use Symfony\Component\Scheduler\Event\FailureEvent;
1718
use Symfony\Component\Scheduler\Event\PostRunEvent;
1819
use Symfony\Component\Scheduler\Event\PreRunEvent;
1920
use Symfony\Component\Scheduler\Generator\MessageGenerator;
@@ -81,10 +82,14 @@ public function run(array $options = []): void
8182
continue;
8283
}
8384

84-
$this->handlers[$message::class]($message);
85-
$ran = true;
85+
try {
86+
$this->handlers[$message::class]($message);
87+
$ran = true;
8688

87-
$this->dispatcher->dispatch(new PostRunEvent($generator->getSchedule(), $context, $message));
89+
$this->dispatcher->dispatch(new PostRunEvent($generator->getSchedule(), $context, $message));
90+
} catch (\Throwable $error) {
91+
$this->dispatcher->dispatch(new FailureEvent($generator->getSchedule(), $context, $message, $error));
92+
}
8893
}
8994
}
9095

src/Symfony/Component/Scheduler/Tests/EventListener/DispatchSchedulerEventListenerTest.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
use Psr\Container\ContainerInterface;
1616
use Symfony\Component\EventDispatcher\EventDispatcher;
1717
use Symfony\Component\Messenger\Envelope;
18+
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
1819
use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
20+
use Symfony\Component\Scheduler\Event\PostRunEvent;
1921
use Symfony\Component\Scheduler\Event\PreRunEvent;
2022
use Symfony\Component\Scheduler\EventListener\DispatchSchedulerEventListener;
2123
use Symfony\Component\Scheduler\Generator\MessageContext;
@@ -33,20 +35,22 @@ public function testDispatchSchedulerEvents()
3335

3436
$schedulerProvider = new SomeScheduleProvider([$defaultRecurringMessage]);
3537
$scheduleProviderLocator = $this->createMock(ContainerInterface::class);
36-
$scheduleProviderLocator->expects($this->once())->method('has')->willReturn(true);
37-
$scheduleProviderLocator->expects($this->once())->method('get')->willReturn($schedulerProvider);
38+
$scheduleProviderLocator->expects($this->any())->method('has')->willReturn(true);
39+
$scheduleProviderLocator->expects($this->any())->method('get')->willReturn($schedulerProvider);
3840

3941
$context = new MessageContext('default', 'default', $trigger, $this->createMock(\DateTimeImmutable::class));
4042
$envelope = (new Envelope(new \stdClass()))->with(new ScheduledStamp($context));
4143

4244
/** @var ContainerInterface $scheduleProviderLocator */
4345
$listener = new DispatchSchedulerEventListener($scheduleProviderLocator, $eventDispatcher = new EventDispatcher());
4446
$workerReceivedEvent = new WorkerMessageReceivedEvent($envelope, 'default');
47+
$workerHandledEvent = new WorkerMessageHandledEvent($envelope, 'default');
4548
$secondListener = new TestEventListener();
4649

4750
$eventDispatcher->addListener(PreRunEvent::class, [$secondListener, 'preRun']);
48-
$eventDispatcher->addListener(PreRunEvent::class, [$secondListener, 'postRun']);
51+
$eventDispatcher->addListener(PostRunEvent::class, [$secondListener, 'postRun']);
4952
$listener->onMessageReceived($workerReceivedEvent);
53+
$listener->onMessageHandled($workerHandledEvent);
5054

5155
$this->assertTrue($secondListener->preInvoked);
5256
$this->assertTrue($secondListener->postInvoked);

0 commit comments

Comments
 (0)