Description
Description
I need to execute a task on a regular basis.
To manage this task I use Messenger, so I can execute it async.
Practically I follow this flow:
- Dispatch the message the first time
- Execute the message the first time
- Schedule the message again to be executed after a certain amount of time (for example, 1 minute)
- Execute the message after 1 minute
- Schedule the message to be executed again 1 minute later
- ... and so on, for... eternity 😅
Now, instead of dispatching a new message each time from inside my MessageHandler, I created a stamp RescheduleStamp
and a corresponding middleware RescheduleMiddleware
.
The middleware does a simple thing: if the message has a RescheduleStamp
, then it schedules another message adding a DelayStamp
to execute it in the future date set through the RescheduleStamp
.
The RescheduleStamp
uses the units of relative time formats (https://www.php.net/manual/en/datetime.formats.relative.php#datetime.formats.relative).
So, I can create a message that has to be rescheduled for eternity in a very easy way:
$message = new EternalMessage($heaven);
$this->messageBus->dispatch($message, [new RescheduleStamp(1, RescheduleStamp::PERIOD_MINUTES)]);
The constant RescheduleStamp::PERIOD_MINUTES
helps avoiding errors:
class RescheduleStamp implements StampInterface
{
public const PERIOD_SECONDS = 'seconds';
public const PERIOD_MINUTES = 'minutes';
public const PERIOD_HOURS = 'hours';
public const PERIOD_DAYS = 'days';
public const PERIOD_WEEKS = 'weeks';
public const PERIOD_MONTHS = 'months';
public const PERIOD_YEARS = 'years';
...
I have a working implementation that I like to merge in Symfony: WDYT?
End note:
May be related to #38459