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
The problem is that worker can't flush batch handlers without feeding a message into them.
Not much to write here without diving deep into details, see the sections below.
This bug can cause multiple hard to track issues in other parts of the system, that depends on the way the queue is processed.
How to reproduce
The bug can be reproduced with any batch handler that does not flush itself without shouldFlush being true.
Currently the Worker class waits for new messages to flush handlers. In general it makes sense, there is no reason to flush batches if there are no new messages since the simplest shouldFlush method that checks current batch size won't change.
But the class also doesn't flush the handlers on stop. And that is an issue.
But there is another problem with the current approach.
For example if we have a handler with the following shouldFlush method:
private function shouldFlush(): bool
{
return $this->batchSize <= \count($this->jobs) || random_int(0, 1) /* some external condition, e.g. timer */;
}
The handler implements shouldFlush method that depends on an external condition that could trigger flush. This might be useful for jobs that are processed in real time. In the current worker implementation the batch might be hanging in memory for a long time if the rate at which the processed messages are generated is low.
To fix the bug and also to enable the previously described use case a listener can be written that flushes batch handlers and calls Worker::ack method on every WorkerRunningEvent/WorkerStoppedEvent event. Alas, this is a hack and not a proper solution that might be integrated into the Messenger component.
Additional Context
No response
The text was updated successfully, but these errors were encountered:
Symfony version(s) affected
5.4, 6.3
Description
The problem is that worker can't flush batch handlers without feeding a message into them.
Not much to write here without diving deep into details, see the sections below.
This bug can cause multiple hard to track issues in other parts of the system, that depends on the way the queue is processed.
How to reproduce
The bug can be reproduced with any batch handler that does not flush itself without
shouldFlush
beingtrue
.Possible Solution
TLDR: to fix write a listener that flushes batch handlers and calls
Worker::ack
method on everyWorkerRunningEvent
(not required, see the explanation below)/WorkerStoppedEvent
event.Use a hack like https://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/ to access
Worker::ack
.Currently the
Worker
class waits for new messages to flush handlers. In general it makes sense, there is no reason to flush batches if there are no new messages since the simplestshouldFlush
method that checks current batch size won't change.But the class also doesn't flush the handlers on stop. And that is an issue.
But there is another problem with the current approach.
For example if we have a handler with the following
shouldFlush
method:The handler implements
shouldFlush
method that depends on an external condition that could trigger flush. This might be useful for jobs that are processed in real time. In the current worker implementation the batch might be hanging in memory for a long time if the rate at which the processed messages are generated is low.To fix the bug and also to enable the previously described use case a listener can be written that flushes batch handlers and calls
Worker::ack
method on everyWorkerRunningEvent
/WorkerStoppedEvent
event. Alas, this is a hack and not a proper solution that might be integrated into the Messenger component.Additional Context
No response
The text was updated successfully, but these errors were encountered: