-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Messenger] Could not acknowledge redis message with BatchHandlerInterface #44400
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
Comments
Same here, could this have something to do with what is stated about In our infra we have Supervisor run 4 instances of the |
Any news @xabbuh? |
@zip-fa since I've properly configured the Supervisor application to register to Redis on a unique DSN this issue seems resolved for me. After translating this Russian blogpost by Алексей Альшенецкий I've came to the following configuration: # messenger.yaml
parameters:
env(CONSUMER_ID): '0'
framework:
messenger:
transports:
async: "redis://%env(REDIS_HOST)%:%env(REDIS_PORT)%/messages/symfony/consumer-%env(CONSUMER_ID)%?auto_setup=true" # supervisor.conf
[program:messenger-consume]
command=php /var/www/html/bin/console messenger:consume async
numprocs=10
autostart=true
autorestart=true
environment = CONSUMER_ID=%(process_num)d Relevant details
|
We're also seeing this issue with only two workers on Azure managed Redis. This is the current config: framework:
messenger:
buses:
messenger.bus.pimcore-core:
middleware:
- doctrine_ping_connection
- doctrine_close_connection
- doctrine_transaction
transports:
pimcore_core:
dsn: '%env(file:MESSENGER_DSN_FILE)%'
options:
delete_after_ack: true
stream: '%env(MESSENGER_GROUP)%'
consumer: '%env(HOSTNAME)%'
pimcore_maintenance:
dsn: '%env(file:MESSENGER_DSN_FILE)%'
options:
delete_after_ack: true
stream: '%env(MESSENGER_GROUP)%'
consumer: '%env(HOSTNAME)%'
pimcore_image_optimize:
dsn: '%env(file:MESSENGER_DSN_FILE)%'
options:
delete_after_ack: true
stream: '%env(MESSENGER_GROUP)%'
consumer: '%env(HOSTNAME)%'
It mostly works, but then something happens and the messages consistently cannot be acknowledged, breaking workers for a while. |
A small reproducing app might help here. |
@nicolas-grekas I expect this to be very hard to reproduce since it might be context specific (in our case, Azure managed Redis), if I was able to reproduce it, I'd be able to fix it. :) I could try to fully debug it if you point me to how this is supposed to work, what are the scenarios where Redis wouldn't be able to acknowledge the message? It was already acknowledged, for example? |
I have the same issue with redis host on K8S or in local. Like you said, after the fail, whatever the batchsize is, that same message will be __invoke every time. If someone else does not do it early, I'll try to find some time to create a small app to reproduce it. FYI: I asked also about it on slack here (exact same issue) public function __invoke(PushMessage $message, Acknowledger $ack = null)
{
dump('__invoke'.$message->key);
return $this->handle($message, $ack);
}
private function process(array $jobs): void
{
foreach ($jobs as [$message, $ack]) {
dump('process'.$message->key);
}
die;
} All dumps display the exact same message->key which are supposed to be uniq. I'm not 100% sure, but even with a dummy consumer like this, without the |
With my experience with this, the problem is that the message is already consumed. So you can try something like this: |
I have the same config - read my first message |
Me and my colleague have managed to fix the problem described here. It is actually not a single bug but a whole pile:
|
@AdamKatzDev, maybe you can share a solution (Redis connection decorator)? |
@lermontex, sure. To anyone that tries to use this crutch, this is a part of the full solution, you need to add UUID to your messages to remove duplicates. The decorator allows to ack and delete messages that don't exist in the redis stream anymore (and you will have to do this, redis transport will try to feed your worker duplicate messages, i.e. the messages that are collected but not processed by the worker at the moment). Also take a look at my previous comment to check other issues that might affect you. src/Messenger/Bridge/Redis/RedisTransportFactoryDecorator.php
src/Messenger/Bridge/Redis/RedisTransportFactoryDecorator.php
config/services.yaml
|
@AdamKatzDev, Thanks! I tried it, but unfortunately, it didn't work for me.
Tell me, please, what do you mean? Is this mandatory if I don't send identical messages to the queue? |
@lermontex
After that you need to ack every duplicate message or you'll get the |
@AdamKatzDev, thanks for your detailed answer! |
While working on this #49028 PR I've realized that I can't fix the issue fully for batch handlers without fixing this issue first. Algorithm is the following:
If (big if) it is guaranteed that a message is always acked/noacked or workers dies if not, then this should work. But introducing a state in |
Hey, thanks for your report! |
So, we've build our own transport instead. We've made some opinionated changes there to make it work as we needed, so it is not a perfect replacement for the Symfony implementation. |
To follow up here, this comment #49028 (comment) says
@AdamKatzDev can you outline the rough idea(s) you had with these new features helping? How would you use the new commands and could this be upstreamed into Symfony? Thanks. Edit: looking at your list of issues here: #44400 (comment) it seems some of them are fixed, some are probably still pending. Could we review it and create the missing issues which describe what we're trying to achieve and what steps need to be taken, how and why? IMO Redis is a popular choice for the Messenger and it makes sense we improve it if possible. |
Fixed in #49539
Not fixed #49026, but there is a crutch #46869 (reply in thread)
We currently use XAUTOCLAIM to claim messages instead of using XPENDING and XCLAIM combo. That simplifies code a lot. |
I could provide the transport implementation in a draft. But I am afraid I won't have time to make the complete PR myself. |
Creating a draft would be a great start IMO because it gives people something actionable to look at and do. 👍 |
fixes symfony#49023, partially fixes symfony#44400
There is also another issue that can be confusing for someone who switch from AWS SQS, for example, and described in #51604 and in #44400 (comment). |
As far as I know this also affects Symfony 7. |
Symfony version(s) affected
5.4.0, 6.0.0
How to reproduce
I have MessengerHandler which makes http requests (with only one parallel consumer):
messenger.yaml:
TestMessageHandler.php:
cli:
MESSENGER_CONSUMER_NAME=test php bin/console messenger:consume test
Code works okay, but when i hit ctrl+c before script finished and start it again, it throws me an error:
I noticed that after consumer crashes or i hit ctrl+c, same message comes to __invoke a few times. When removing BatchHandlerInterface it starts to work as excepected without any issue.
Possible Solution 1 (a bad one)
Test.php:
TestMessageHandler.php:
Possible Solution 2
Comment __destruct in Symfony\Component\Messenger\Handler\Acknowledger.php
Handler.php:
Additional Context
No response
The text was updated successfully, but these errors were encountered: