Skip to content
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

Check key type first in blocking functions #1130

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

prvyk
Copy link
Contributor

@prvyk prvyk commented Mar 23, 2025

Whenever Redis gets a blocking pop command, it tries to pop the value first, and if the value is of the wrong type, it aborts with a WRONGTYPE error. Note that setting the key with the wrong type afterwards (while the timeout is on), will not emit a WRONGTYPE error.

This is arguably in 'bug compatible' category - but blocking when the client may not expect it is best avoided.

@badrishc badrishc requested a review from TalZaccai March 25, 2025 00:41
@prvyk prvyk force-pushed the blockingpoptype branch from 7cc05c7 to 4317643 Compare March 27, 2025 02:53
Copy link
Contributor

@TalZaccai TalZaccai left a comment

Choose a reason for hiding this comment

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

Thanks for raising this issue!

What Redis does is actually a bit more nuanced here. Let me describe BLPOP for instance - initially, it checks the keys in the order that they are given, if a key has a List value and has an item - that item gets popped. If a value is not a List and is not none - it returns an error.
So essentially, if I have a list of keys k1 (list), k2 (non-list), k3 (list) - it will only fail if k1 is empty.
For example:
image

Another behavioral detail to keep in mind, if we block on an empty item that gets set to a different type, the operation will continue to wait and will only be released if the type changed to the correct type and an item was found:
image

That being said, what I think the solution should be -
That initial lookup loop for existing items happens in CollectionItemBroker.InitializeObserver. So, we need to implement a logic where if TryGetResult indicates that the value in key is of the wrong type and return an error accordingly.

Let me know if that makes sense & if you have any follow-up questions.

@prvyk prvyk marked this pull request as draft March 28, 2025 01:04
@prvyk prvyk force-pushed the blockingpoptype branch 3 times, most recently from bc24cb9 to 1c0da12 Compare March 28, 2025 21:51
@prvyk
Copy link
Contributor Author

prvyk commented Mar 28, 2025

What Redis does is actually a bit more nuanced here. Let me describe BLPOP for instance - initially, it checks the keys in the order that they are given...
That being said, what I think the solution should be - That initial lookup loop for existing items happens in CollectionItemBroker.InitializeObserver. So, we need to implement a logic where if TryGetResult indicates that the value in key is of the wrong type and return an error accordingly.

Let me know if that makes sense & if you have any follow-up questions.

It makes perfect sense. I considered that implementation strategy, but wanted to avoid touching the event code, and didn't notice the (valid object) (invalid object) behaviour, so went for the simpler initial GetKeyType()... But this doesn't leave much choice but to change the event code.

@prvyk prvyk force-pushed the blockingpoptype branch 2 times, most recently from 1add783 to cda2a3a Compare March 28, 2025 23:12
@prvyk prvyk marked this pull request as ready for review March 28, 2025 23:46
prvyk added 2 commits March 29, 2025 08:18
@prvyk prvyk force-pushed the blockingpoptype branch from cda2a3a to dd418bf Compare March 29, 2025 05:25
@prvyk prvyk requested a review from TalZaccai March 29, 2025 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants