-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Add LMPOP/BLMPOP commands. #9373
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
Conversation
We want to add COUNT option for BLPOP. But we can't do it without breaking compatibility. So this commit introduce a new command. Syntax for the new LMPOP command: LMPOP numkeys [<key> ...] LEFT|RIGHT [COUNT count] [BLOCK timeout] Some background: - LPOP takes one key, and can return multiple elements. - BLPOP takes multiple keys, but returns one element from just one key. - [B]LMPOP can take multiple keys and return multiple elements from just one key. Note that [B]LMPOP can take multiple keys, it eventually operates on just one key. And it will propagate as LPOP or RPOP with the COUNT option. As a new command, it still return NIL if we can't pop any elements. For the normal response is nested arrays in RESP2 and RESP3, like: [B]LMPOP 1) keyname 2) 1) element1 2) element2
|
Some usage: with block: |
oranagra
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gave you some comments,
the most important one is about separating reply, popping and deleting roles properly between common code with other parts of redis.
i haven't reviewed the tests yet. i see there are quite a lot of them, can you please describe what you did to create them? i.e. did you just copy all the existing tests for BLPOP or something of that sort? any advise of how to review that?
|
I think we had a preference for having separate blocking commands based on feedback from client developers. Just making a note here. I'd also prefer: The syntax of having num keys is sort of awkward for clients to do. |
|
@madolson if all the keys are in the end (without any keyword) we can't have optional arguments (it's gonna be hard for clients to detect) |
|
I think having a "keys" keyword works too. |
|
clients prefer some keyword at unknown index rather than keynum at a fixed index? |
|
for the record: i also prefer having a separate blocking command rather than BLOCK |
|
@enjoy-binbin sorry for the back and forth, please make the changes to separate LMPOP and BLMPOP. regarding the keyword vs keynum discussion, even if we do with with keyword, we'll still need a keynum argument, i think a keynum at a fixed argument, like we have for EVAL and ZUNION is fine. |
|
Sure. no problems. I will take care of the LMPOP/BLMPOP and other suggestions from the review. agree madolson's comment below |
|
It seemed more user friendly to not have to compute the length, but it's not something I feel strongly about. We should also probably write down our command structure best practices though, being consistent is more important than what we pick. |
@madolson what do you mean? |
|
@oranagra If I'm doing it on the cli manually: Is slightly easier than It's much easier to get the count wrong and have a non-obvious error. But I also acknowledge that from an internal implementation perspective, having the fixed position number of arguments is also nice. Also, most clients will abstract this away. |
|
@madolson in your first example there's no key_count, do you mean that as soon as we hit the KEYS argument, the remainder of the arguments are keys? |
|
I think the pros of using "keynum" outweigh the cons... |
1. separate LMPOP and BLMPOP 2. remove 'del' arg 3. pop inside serveClientBlockedOnList 4. other fix from review Co-authored-by: Oran Agra <oran@redislabs.com>
|
looking at the new command syntax: i think this last argument thing is what we have in BLPOP today, is bad.
if we take the second option, default timeout could be 0, i.e. infinite. |
Co-authored-by: Oran Agra <oran@redislabs.com>
Minor preference for this one. In all other blocking commands the timeout is a required argument and I think that makes sense. I don't think timeout should be optional/default to 0. Even for XADD you can't do blocking with an implied default. |
1b55f8d to
302352d
Compare
|
@enjoy-binbin please prepare a redis-doc PR |
|
Doc PR created at redis/redis-doc#1636 |
|
Question: are these commands officially deprecating |
|
i didn't intend to deprecate these, but maybe that't the logical thing to do. |
|
@oranagra I'm not in favor of deprecating them, the four essential list commands are [L|R]PUSH and [L|R]POP and they are easy to understand. I don't want to deprecate half of them for a new command that is both more complex and introduces more inconsistencies. |
|
@madolson i agree, but trying to find a logical justification to explain why we did that for some and don't do that here. |
|
RPOPLPUSH was an outlier command that wasn't able to implement all use cases, so that one makes sense to deprecate. I don't really know if I agree the other two should have been deprecated. Having a single ZRANGE is much nicer than a half dozen variants though. |
|
Arguably LPOP and BLPOP are also not "able to implement all use cases" (I.E popping multiple elements or from multiple keys). But ok, it's just a Metadata flag, it doesn't really do anything, and we can always add it later. |
Very well. I'll go over the docs again in light of this. |
This is similar to the recent addition of LMPOP/BLMPOP (#9373), but zset. Syntax for the new ZMPOP command: `ZMPOP numkeys [<key> ...] MIN|MAX [COUNT count]` Syntax for the new BZMPOP command: `BZMPOP timeout numkeys [<key> ...] MIN|MAX [COUNT count]` Some background: - ZPOPMIN/ZPOPMAX take only one key, and can return multiple elements. - BZPOPMIN/BZPOPMAX take multiple keys, but return only one element from just one key. - ZMPOP/BZMPOP can take multiple keys, and can return multiple elements from just one key. Note that ZMPOP/BZMPOP can take multiple keys, it eventually operates on just on key. And it will propagate as ZPOPMIN or ZPOPMAX with the COUNT option. As new commands, if we can not pop any elements, the response like: - ZMPOP: Return a NIL in both RESP2 and RESP3, unlike ZPOPMIN/ZPOPMAX return emptyarray. - BZMPOP: Return a NIL in both RESP2 and RESP3 when timeout is reached, like BZPOPMIN/BZPOPMAX. For the normal response is nested arrays in RESP2 and RESP3: ``` ZMPOP/BZMPOP 1) keyname 2) 1) 1) member1 2) score1 2) 1) member2 2) score2 In RESP2: 1) "myzset" 2) 1) 1) "three" 2) "3" 2) 1) "two" 2) "2" In RESP3: 1) "myzset" 2) 1) 1) "three" 2) (double) 3 2) 1) "two" 2) (double) 2 ```
The previous code did not check whether COUNT is set. So we can use `lmpop 2 key1 key2 left count 1 count 2`. This situation can occur in LMPOP/BLMPOP/ZMPOP/BZMPOP commands. LMPOP/BLMPOP introduced in redis#9373, ZMPOP/BZMPOP introduced in redis#9484.
In redis#9373, actually need to replace `$rd $pop blist1{t} blist2{t} 1` with `bpop_command_two_key $rd $pop blist1{t} blist2{t} 1` but forgot to delete the latter. This doesn't affect the test, because the later assert_error "WRONGTYPE" is expected (and right). And if we read $rd again, it will get the wrong result, like 'ERR unknown command 'BLMPOP_LEFT' | 'BLMPOP_RIGHT'
In #9373, actually need to replace `$rd $pop blist1{t} blist2{t} 1` with `bpop_command_two_key $rd $pop blist1{t} blist2{t} 1` but forgot to delete the latter. This doesn't affect the test, because the later assert_error "WRONGTYPE" is expected (and right). And if we read $rd again, it will get the wrong result, like 'ERR unknown command 'BLMPOP_LEFT' | 'BLMPOP_RIGHT'
In redis#9373, actually need to replace `$rd $pop blist1{t} blist2{t} 1` with `bpop_command_two_key $rd $pop blist1{t} blist2{t} 1` but forgot to delete the latter. This doesn't affect the test, because the later assert_error "WRONGTYPE" is expected (and right). And if we read $rd again, it will get the wrong result, like 'ERR unknown command 'BLMPOP_LEFT' | 'BLMPOP_RIGHT'
We want to add COUNT option for BLPOP.
But we can't do it without breaking compatibility due to the command arguments syntax.
So this commit introduce two new commands.
Syntax for the new LMPOP command:
LMPOP numkeys [<key> ...] LEFT|RIGHT [COUNT count]Syntax for the new BLMPOP command:
BLMPOP timeout numkeys [<key> ...] LEFT|RIGHT [COUNT count]Some background:
Note that LMPOP/BLMPOP can take multiple keys, it eventually operates on just one key.
And it will propagate as LPOP or RPOP with the COUNT option.
As a new command, it still return NIL if we can't pop any elements.
For the normal response is nested arrays in RESP2 and RESP3, like:
I.e. unlike BLPOP that returns a key name and one element so it uses a flat array,
and LPOP that returns multiple elements with no key name, and again uses a flat array,
this one has to return a nested array, and it does for for both RESP2 and RESP3 (like SCAN does)
Some discuss can see: #766 #8824