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

Skip to content

[Scheduler] Expose the run date? #50085

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tucksaun opened this issue Apr 20, 2023 · 5 comments · Fixed by #50130
Closed

[Scheduler] Expose the run date? #50085

tucksaun opened this issue Apr 20, 2023 · 5 comments · Fixed by #50130

Comments

@tucksaun
Copy link
Contributor

Description

I'm currently assessing the possibility for one of my clients to switch their scheduled task to the new Scheduler component once 6.3 is released.
Everything is going great so far but I found one thing limiting them: the fact that it is not possible to access the run datetime. And using the current datetime does not really seems appropriate to me as it could be not in sync if the Scheduler is catching up on some missed schedules.

This looks to me like a quite common use case with scheduled tasks (when one wants to run some kind of report generation for example) where you need the current month or week to know which timespan to use. And so supporting it looks appealing.

Any thoughts? Does supporting this use case would make sense?
/cc @fabpot @kbond (as it seems to me you have been the most active on this component so far :) )

I did some quick fiddling and it seems to be possible to yield the $time from the MessageGenerator, add it time to the ScheduledStamp and then the user is free to do what they want with a Middleware or a listener.
I have also tried to think about it could be done with events (#49803 ) but introducing a dependency to the Event Dispatcher only for this seems a bit overkill.
So far, I have not been able to find another more satisfactory way of supporting this use case.

Maybe someone has a better idea?

Example

Here is the listener that I wrote in the app to support this use case, as you can see it becomes relatively easy to get the date and transmit it (or do some logging or whatever you want):

#[AsEventListener(WorkerMessageReceivedEvent::class)]
class ScheduledStampListener
{
    public function __invoke(WorkerMessageReceivedEvent $event): void
    {
        if(!$event->getEnvelope()->last(ScheduledStamp::class)) {
            return;
        }

        if (!$event->getEnvelope()->getMessage() instanceof ManagementInformationReportCommand) {
            return;
        }

        $event->addStamps(new HandlerArgumentsStamp([$event->getEnvelope()->last(ScheduledStamp::class)->at]));
    }
}
@tucksaun tucksaun changed the title [Scheduler] Expose the run date [Scheduler] Expose the run date? Apr 20, 2023
@kbond
Copy link
Member

kbond commented Apr 20, 2023

To clarify, you're suggesting adding the timestamp the message should have run at on the ScheduledStamp (not the time it was dispatched)?

I did some quick fiddling and it seems to be possible to yield the $time from the MessageGenerator

What does that look like?

@tucksaun
Copy link
Contributor Author

To clarify, you're suggesting adding the timestamp the message should have run at on the ScheduledStamp (not the time it was dispatched)?

Yes indeed (way more clear this way)

What does that look like?

Something like this:

diff --git a/src/Symfony/Component/Scheduler/Generator/MessageGenerator.php b/src/Symfony/Component/Scheduler/Generator/MessageGenerator.php
index 2f9743c59b..3db2ea4a49 100644
--- a/src/Symfony/Component/Scheduler/Generator/MessageGenerator.php
+++ b/src/Symfony/Component/Scheduler/Generator/MessageGenerator.php
@@ -70,7 +70,7 @@ final class MessageGenerator implements MessageGeneratorInterface
             }
 
             if ($yield) {
-                yield $message;
+                yield $time => $message;
                 $this->checkpoint->save($time, $index);
             }
         }
diff --git a/src/Symfony/Component/Scheduler/Messenger/ScheduledStamp.php b/src/Symfony/Component/Scheduler/Messenger/ScheduledStamp.php
index 4b1b5cf1b5..4cb8543b69 100644
--- a/src/Symfony/Component/Scheduler/Messenger/ScheduledStamp.php
+++ b/src/Symfony/Component/Scheduler/Messenger/ScheduledStamp.php
@@ -18,4 +18,7 @@ use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
  */
 final class ScheduledStamp implements NonSendableStampInterface
 {
+    public function __construct(public readonly \DateTimeImmutable $at)
+    {
+    }
 }
diff --git a/src/Symfony/Component/Scheduler/Messenger/SchedulerTransport.php b/src/Symfony/Component/Scheduler/Messenger/SchedulerTransport.php
index 9625e8c41b..6955208e1b 100644
--- a/src/Symfony/Component/Scheduler/Messenger/SchedulerTransport.php
+++ b/src/Symfony/Component/Scheduler/Messenger/SchedulerTransport.php
@@ -29,7 +29,7 @@ class SchedulerTransport implements TransportInterface
     public function get(): iterable
     {
         foreach ($this->messageGenerator->getMessages() as $message) {
-            yield Envelope::wrap($message, [new ScheduledStamp()]);
+            yield Envelope::wrap($message, [new ScheduledStamp($time)]);
         }
     }
 

@kbond
Copy link
Member

kbond commented Apr 20, 2023

Something like this:

Ah ok. I would like more context like this as well (see #49865, #49864 and #49838). Having the trigger available on stamp could be useful too. Using stamps makes the most sense but that creates a hard-dep on messenger.

I personally think we should create a hard-dep on messenger but @fabpot doesn't agree. I've been experimenting with building my own wrappers to add the context (stamps) I need to messages (for my reporting system). This example is something that cannot be easily added.

Maybe we need a MessengerMessageGenerator that shares the logic from MessageGenerator but wraps messages in an Envelope and adds additional context as a stamp.

@tucksaun
Copy link
Contributor Author

that creates a hard-dep on messenger.

I'm not sure a hard dependency is required if the stamping is done in the SchedulerTransport.

@kbond
Copy link
Member

kbond commented Apr 21, 2023

We don't have access to the data we need there. (Assuming we want more than this timestamp added to the stamp)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants