Description
Symfony version(s) affected
6.3
Description
When you have multiple messages in the same schedule, only the timestamp of the latest message will be saved in the cache. When your consumer stops (by --time-limit
or unexpected) the next run date for the other messages will be calculated again. So when you have recurring messages for 1 minute and 30 minutes, with a restart policy of 60 seconds, the 30 minutes message will never be executed when you do do not pass the from
argument.
As a temporary workaround I disabled jitter and set the from
argument to a date in the past on 00:00:00, which makes the message be calculated based on that (so always on 00:30, 01:00 etc.). However if the consumer is restarting or down due to a crash at that moment, they will not be catched up when booting up the consumer again as the last-ran-date is not cached. This is why I disabled jitter to reduce that risk to the specific time instead of adding the jitter time to that.
How to reproduce
- Create a stateful schedule with a recurring message scheduled every minute (message A), and one message every 30 minutes (message B). Do not pass a from date.
- Dump the next run dates in
MessageGenerator.php
- Start the consumer
- Assert that message A is scheduled for +1 minute, assert that message B is scheduled for +30 minutes
- Wait a minute for message A to be executed
- Restart the consumer
- Message A is scheduled for +1 minute (relative to the previous datetime), message B is scheduled for +30 minutes again (so ~1 minute later than the last next run date it dumped)
Possible Solution
Edit the caching so it works per message, not per schedule.
Additional Context
I created a PR that got merged in 6.3.2 that fixed the from
argument. This fixed the scheduler from executing 30 minute messages every minutely restart for example, but due to this bug that fix now causes those messages to never get executed. So unless you pass a from
date, those schedules are completely broken at the moment.