Skip to content

[Messenger] Add option to prevent Redis from deleting messages on rejection #36727

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

Merged
merged 1 commit into from
Sep 4, 2020

Conversation

Steveb-p
Copy link
Contributor

@Steveb-p Steveb-p commented May 6, 2020

Unless delete_after_ack configuration is set to true.

Introduces delete_after_reject configuration property.

Q A
Branch? master
Bug fix? yes
New feature? no yes (introduces config property)
Deprecations? no
Tickets Fix #36619
License MIT

Redis Messenger transport deletes messages when rejecting, causing other consumers / applications to be unable to reach that message.

This affects primarily cases where Messenger component is used to read/write with other, third party applications.

@Steveb-p Steveb-p requested a review from sroze as a code owner May 6, 2020 13:54
@Steveb-p Steveb-p changed the title Stop deleting messages on rejection [Messenger] Prevent Redis from deleting messages on rejection May 6, 2020
@nicolas-grekas
Copy link
Member

Then there is going to be zero different between calling reject() and calling ack(). This looks suspicious to me.

@nicolas-grekas nicolas-grekas added this to the 5.1 milestone May 8, 2020
@nicolas-grekas nicolas-grekas changed the base branch from master to 5.1 May 16, 2020 12:34
@soyuka
Copy link
Contributor

soyuka commented May 20, 2020

Maybe that introducing a new delete_after_reject option would make more sense. As a reminder, this option is here to cover memory usage (7c416a7) although #36619 is an issue where rejected (not acknowledged) messages would not be available to other consumers. Acknowledged messages would could still be deleted to spare memory even though rejected ones could persist.

@Steveb-p
Copy link
Contributor Author

Steveb-p commented May 21, 2020

Then there is going to be zero different between calling reject() and calling ack(). This looks suspicious to me.

Whoops, missed the comment.

Pretty much yes, rejection and acknowledgement becomes undistinguishable. From my point of view, acknowledgement means "Yup, I've seen this message and I've handled it". Whether it was rejected or handled ok is not possible to pass to Redis as there is no XREJect command anyway.

This is similar to how Kafka handles messages, which is what Redis streams are based on conceptually. It is simply a structured log that you go through, acknowledging messages as they come (meaning, "I've read it").

https://redis.io/topics/streams-intro

Consumer groups were initially introduced by the popular messaging system called Kafka (TM). Redis reimplements a similar idea in completely different terms, but the goal is the same: to allow a group of clients to cooperate consuming a different portion of the same stream of messages.

As you can see in the original, XACK was sent to Redis just before XDEL anyway. Deleting the message causes other consumer groups to be unable to handle that message, despite potentially being able to.
In my case, other consumer group is simply another application. Errors during deserialization caused Worker to reject the message and delete, even though another app was perfectly able to work with it.

As a reminder, this option is here to cover memory usage

(delete_after_ack) I would like to add some sort of warning/note to documentation of this feature (probably in another PR?). I can see where it comes from, but it's "only" reasonable to delete messages if only one consumer group is assumed (that is, Messenger component is treated as internal application queue, not as a method of different application parts / applications to speak to one another).
In cases where another consumer group shows up, it breaks consumer group functionality in Redis.

@Steveb-p
Copy link
Contributor Author

Steveb-p commented May 26, 2020

@sroze could you give your opinion on this if you have some spare time? I'd like to adjust the PR to match.

Does this need some tests to be added, or will it be good as-is, even with new configuration property delete_after_reject?

EDIT: Also, what delete_after_reject default value should be? From my point of view it should maybe follow the delete_after_ack property if it is set, and be false otherwise?
I think that this would prevent messages from being deleted (which is what surprised me in the original issue) while keeping the intent of managing redis's memory in delete_after_ack = true case.

EDIT2: I rebased the PR to the current master 5.1 branch. And I've put a lot of people on reviever list by doing so... Sorry 😞 😢

Copy link
Member

@chalasr chalasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabpot
Copy link
Member

fabpot commented Jun 22, 2020

I agree with @chalasr, this should target 5.2 (aka master).

@Steveb-p
Copy link
Contributor Author

@fabpot @chalasr I'll rebase and adjust the PR accordingly.

Hopefully I won't pull half of the community into it this time 🙈

@Steveb-p Steveb-p changed the base branch from 5.1 to master June 22, 2020 17:11
@Steveb-p Steveb-p force-pushed the redis-transport-rejection branch from 4a71386 to d9beed8 Compare June 22, 2020 17:11
@chalasr chalasr added Feature and removed Bug labels Jun 23, 2020
@chalasr chalasr modified the milestones: 5.1, next Jun 23, 2020
@Steveb-p Steveb-p marked this pull request as draft July 20, 2020 05:28
@Steveb-p Steveb-p force-pushed the redis-transport-rejection branch from d9beed8 to a4576cb Compare July 20, 2020 05:34
@Steveb-p Steveb-p marked this pull request as ready for review July 20, 2020 05:35
@nicolas-grekas nicolas-grekas changed the title [Messenger] Prevent Redis from deleting messages on rejection [Messenger] Add option to prevent Redis from deleting messages on rejection Sep 3, 2020
@nicolas-grekas nicolas-grekas force-pushed the redis-transport-rejection branch from a4576cb to 75cce6d Compare September 3, 2020 20:31
@nicolas-grekas nicolas-grekas force-pushed the redis-transport-rejection branch from 75cce6d to 135c650 Compare September 3, 2020 20:33
@fabpot
Copy link
Member

fabpot commented Sep 4, 2020

Thank you @Steveb-p.

@fabpot fabpot merged commit 05bdfc9 into symfony:master Sep 4, 2020
@chalasr chalasr removed their request for review September 7, 2020 09:17
@nicolas-grekas nicolas-grekas modified the milestones: next, 5.2 Oct 5, 2020
@fabpot fabpot mentioned this pull request Oct 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Messenger] Redis Transport removes message from stream on rejection
6 participants