Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.6k
[Scheduler] pre_run and post_run events#51805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
carsonbot commentedOct 2, 2023
Hey! Thanks for your PR. You are targeting branch "6.4" but it seems your PR description refers to branch "6.4 for features". Cheers! Carsonbot |
c523449
to70218b2
Compare70218b2
toc90b629
CompareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Quick initial review
namespace Symfony\Component\Scheduler\Event; | ||
final class SchedulerEvents |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm pretty sure we don't want this class alias system anymore. We just the use event's FQCN.
@@ -99,6 +102,10 @@ public function run(array $options = []): void | |||
if ($queueNames) { | |||
$envelopes = $receiver->getFromQueues($queueNames); | |||
} else { | |||
if (method_exists($receiver, 'getMessageGenerator')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I don't think we'll want the messenger to be aware of the scheduler. Ideally, we want these events dispatched in the scheduler but can't currently think of how.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Indeed, as discussed, I will add listeners that listens to the WorkerMessageReceivedEvent and to the WorkerMessageHandledEvent and dispatch the corresponding scheduler event. Thank you for your feedback!
class PostRunEvent | ||
{ | ||
public function __construct(private readonly MessageGenerator $messageGenerator, private readonly Envelope $envelope) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Assuming we dispatch these events in the scheduler itself, we cannot useEnvelope
here as it could be any object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Indeed the standalone usage
use Symfony\Component\Scheduler\Exception\LogicException; | ||
use Symfony\Contracts\Cache\CacheInterface; | ||
final class Schedule implements ScheduleProviderInterface | ||
{ | ||
public function __construct(private readonly EventDispatcherInterface $dispatcher) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This would need to be optional.
c90b629
to0a0fe36
Compare$schedulerTransport = $this->receiverLocator->get($event->getReceiverName()); | ||
$schedule = $schedulerTransport->getMessageGenerator()->schedule(); | ||
$this->eventDispatcher?->dispatch(new PostRunEvent($schedule, $messageContext, $envelope->getMessage())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It seems that I would need the same info for pre_run and post_run event.
I will handle this code duplication.
99f8d96
toc30f5f2
CompareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Just some CS stuff for now.
public function __construct(private readonly ?EventDispatcherInterface $dispatcher = null) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
publicfunction __construct(privatereadonly ?EventDispatcherInterface$dispatcher =null) | |
{ | |
publicfunction __construct( | |
privatereadonly ?EventDispatcherInterface$dispatcher =null, | |
) { |
public function __construct(private readonly ScheduleProviderInterface $schedule, private readonly MessageContext $messageContext, private readonly object $message) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
publicfunction __construct(privatereadonlyScheduleProviderInterface$schedule,privatereadonlyMessageContext$messageContext,privatereadonlyobject$message) | |
{ | |
publicfunction __construct( | |
privatereadonly ScheduleProviderInterface$schedule, | |
privatereadonly MessageContext$messageContext, | |
privatereadonly object$message, | |
) { |
public function __construct(private readonly ScheduleProviderInterface $schedule, private readonly MessageContext $messageContext, private readonly object $message) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
publicfunction __construct(privatereadonlyScheduleProviderInterface$schedule,privatereadonlyMessageContext$messageContext,privatereadonlyobject$message) | |
{ | |
publicfunction __construct( | |
privatereadonly ScheduleProviderInterface$schedule, | |
privatereadonly MessageContext$messageContext, | |
privatereadonly object$message, | |
) { |
{ | ||
public function __construct( | ||
private readonly ContainerInterface $receiverLocator, | ||
private readonly ?EventDispatcherInterface $eventDispatcher = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
privatereadonly ?EventDispatcherInterface$eventDispatcher =null | |
privatereadonly ?EventDispatcherInterface$eventDispatcher =null, |
@@ -3,6 +3,7 @@ | |||
namespace Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger; | |||
use Symfony\Component\Cache\Adapter\ArrayAdapter; | |||
use Symfony\Component\EventDispatcher\EventDispatcher; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Not used?
->args([ | ||
service('messenger.receiver_locator'), | ||
service('event_dispatcher'), | ||
]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
]) | |
]) |
Uh oh!
There was an error while loading.Please reload this page.
class PreRunEvent | ||
{ | ||
private bool $isCancel = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
private bool$isCancel =false; | |
private bool$isCancelled =false; |
4f8417b
to49d909f
CompareTo access the Schedule, it has been decided to inject the transports via the locator service ( |
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Component/Messenger/EventListener/DispatchSchedulerEventListener.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Component/Messenger/EventListener/DispatchSchedulerEventListener.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
49d909f
tof2cfe76
CompareUh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Component/Scheduler/EventListener/DispatchSchedulerEventListener.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Component/Scheduler/EventListener/DispatchSchedulerEventListener.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Component/Scheduler/Generator/MessageGeneratorInterface.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
f462be9
toffb8279
Compareinterface MessageGeneratorInterface | ||
{ | ||
/** | ||
* @return iterable<MessageContext, object> | ||
*/ | ||
public function getMessages(): iterable; | ||
public function getSchedule(): Schedule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I'm uncomfortable adding this method to the interface as a MessageGenerator implementation might not use a Schedule.
In any case, I don't see a reason to interact with the schedule before or after handling a message; it doesn't seem right (especially as we now - in 6.4 - have other ways) and again a Schedule is not a requirement to send scheduled messages.
I would recommend removing the Schedule from the events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This is the case when a message is scheduled to be sent every x hours until an event occurs.
It cannot be processed in the handler (messenger case), because it cannot be already processed at that time. The time at which its state (to be processed or not) can change lies within this x-hour interval. The aim, for example in pre_run, is to be able to check (before sending it to the handler) whether it is still relevant or whether, on the contrary, it should be removed from the stack of messages to be processed (since, for example, it will not have to be sent again if it has been processed in the meantime). The aim is to have access to the schedule and to be able to use the remove method, for example, which will recalculate the messages to be processed (using the setRestart introduced in 6.4).
Alternatively, I could inject the ScheduleProviderInterface directly into the event ?
what I don't understand is that on the Scheduler class side, generators will have a Schedule viaScheduleProviderInterface $scheduleProvider
.
Sorry if I misunderstood your point/comment
ffd4881
todc1d61e
CompareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM now (just a few minor comments).
use Symfony\Component\Scheduler\Tests\Messenger\SomeScheduleProvider; | ||
use Symfony\Component\Scheduler\Trigger\TriggerInterface; | ||
class DispatchSchedulerEventListenerTest extends TestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Must be moved to the Scheduler component test suite.
->args([ | ||
tagged_locator('scheduler.schedule_provider', 'name'), | ||
service('event_dispatcher'), | ||
]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
]) | |
]) |
Uh oh!
There was an error while loading.Please reload this page.
@@ -62,8 +66,23 @@ public function run(array $options = []): void | |||
$ran = false; | |||
foreach ($this->generators as $generator) { | |||
foreach ($generator->getMessages() as $message) { | |||
foreach ($generator->getMessages() as $context => $message) { | |||
if ($this->dispatcher) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
What about having testing!$this->dispatcher
to have less code in the condition?
use Symfony\Component\Scheduler\Exception\LogicException; | ||
use Symfony\Contracts\Cache\CacheInterface; | ||
final class Schedule implements ScheduleProviderInterface | ||
{ | ||
public function __construct( | ||
private readonly ?EventDispatcherInterface $dispatcher = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
privatereadonly ?EventDispatcherInterface$dispatcher =null | |
privatereadonly ?EventDispatcherInterface$dispatcher =null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
(when last comments from Fabien will be addressed)
edecb50
to49f05e3
Compare49f05e3
to20fd21a
CompareThank you@alli83. |
This PR was merged into the 6.4 branch.Discussion----------[Scheduler] Fix dev requirements| Q | A| ------------- | ---| Branch? | 6.4| Bug fix? | yes| New feature? | no| Deprecations? | no| Tickets | Follow-up of#51805| License | MITThis should turn the CI greenCommits-------f241ed9 [Scheduler] Fix dev requirements
This PR was merged into the 6.4 branch.Discussion----------[Scheduler] Add `FailureEvent`| Q | A| ------------- | ---| Branch? | 6.4| Bug fix? | no| New feature? | yes| Deprecations? | no| Tickets || License | MITFollowing PR#51805, It would be interesting to add a `failureEvent` allowing you, for instance, to remove the recurring message, depending on the error caught.Commits-------891a404 [Scheduler] Add failureEvent
Uh oh!
There was an error while loading.Please reload this page.
Based on#49803@kbond and taking into account#51553
The aim of this PR is to be able to act on the accumulated messages 'if something happens' and to be able to recalculate the heap via events (currently pre_run and post_run).
The aim is to have access to
This PR would complement@Jeroeny#51553 PR by enabling action via events.