You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When we send envelop with negative delay with messenger configured with Redis bridge, messages are immediately processed.
But it's not the case with Doctrine bridge because here, available_at column of the database queue table is wrongly set.
How to reproduce
First we calc a $delayStamp that is representing the delay between the expected execution time (x day in the past) and the current time when we create the envelop (now).
Because of the expected execution time is in the past, we want it to be executed with no delay.
$negativeDelayStamp = (($expectedExecuteAt->getTimestamp() - (new DateTime('now'))->getTimestamp()) * 1000);
Here we dispatch a simple envelop with a negative DelayStamp
$this->messageBus->dispatch(
new Envelope(new MyMessage(), [
new DelayStamp($negativeDelayStamp),
]));
Next in Symfony\Component\Messenger\Bridge\Doctrine\Transport\Connection $availableAt is calculated using the delay sent :
Because of the + in sprintf('+%d seconds', $delay / 1000) , the negative delay will be interpreted positively (ex: -1000 will be interpreted as +1000).
So instead of set availableAt at the expected execution time, x second in the past, it will set availableAt at the x second in the future.
Possible Solution
I see multiple solution here :
remove the + in $availableAt = $now->modify(sprintf('+%d seconds', $delay / 1000));
throw an exception if negative delay is not a wanted feature
do nothing and let the devs verify the delay value before they sent the envelop
Additional Context
No response
The text was updated successfully, but these errors were encountered:
Negative delays in DelayStamp are tested since #38484 and I admit I don't see which use-cases this covers 🤔 I guess this would even make some transports crash but none seem to guard against that. Do you recall about this @Nyholm?
This PR was squashed before being merged into the 5.4 branch.
Discussion
----------
[Messenger] Fix using negative delay
| Q | A
| ------------- | ---
| Branch? | 5.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Issues | Fix#50833
| License | MIT
Fixes using negative delays when sending messages. Cherry-picked from #53088.
Commits
-------
af1517e [Messenger] Fix using negative delay
Symfony version(s) affected
5.4.25
Description
When we send envelop with negative delay with messenger configured with Redis bridge, messages are immediately processed.
But it's not the case with Doctrine bridge because here, available_at column of the database queue table is wrongly set.
How to reproduce
First we calc a $delayStamp that is representing the delay between the expected execution time (x day in the past) and the current time when we create the envelop (now).
Because of the expected execution time is in the past, we want it to be executed with no delay.
Here we dispatch a simple envelop with a negative DelayStamp
Next in Symfony\Component\Messenger\Bridge\Doctrine\Transport\Connection $availableAt is calculated using the delay sent :
Because of the
+
insprintf('+%d seconds', $delay / 1000)
, the negative delay will be interpreted positively (ex: -1000 will be interpreted as +1000).So instead of set availableAt at the expected execution time, x second in the past, it will set availableAt at the x second in the future.
Possible Solution
I see multiple solution here :
remove the
+
in$availableAt = $now->modify(sprintf('+%d seconds', $delay / 1000));
throw an exception if negative delay is not a wanted feature
do nothing and let the devs verify the delay value before they sent the envelop
Additional Context
No response
The text was updated successfully, but these errors were encountered: