Skip to content

Add ZMPOP/BZMPOP commands.#9484

Merged
oranagra merged 12 commits intoredis:unstablefrom
enjoy-binbin:add_zmpop_bzmpop
Sep 23, 2021
Merged

Add ZMPOP/BZMPOP commands.#9484
oranagra merged 12 commits intoredis:unstablefrom
enjoy-binbin:add_zmpop_bzmpop

Conversation

@enjoy-binbin
Copy link
Contributor

@enjoy-binbin enjoy-binbin commented Sep 10, 2021

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

This is similar to the previous LMPOP/BLMPOP, except for 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 is the same as before:
- ZMPOP: Return an emptyarray in both RESP2 and RESP3, like ZPOPMIN/ZPOPMAX.
- 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
```
@oranagra
Copy link
Member

Some background on the response format.
It was discussed here: #8824 (comment)
And later in #9373

First, like ZPOPMIN we can't use a RESP3 map since the order matters.
Secondly, like the recent LMPOP we decided not to use a flat array in RESP2 (unlike ZPOPMIN, but like SCAN always did).
And although semantically we can return an array of triplets, repeating the key name for each pair, since we always pop only from one key, we decided to return the key name only once.

@oranagra
Copy link
Member

As new commands, if we can not pop any elements, the response is the same as before:
ZMPOP: Return an emptyarray in both RESP2 and RESP3, like ZPOPMIN/ZPOPMAX.
BZMPOP: Return a NIL in both RESP2 and RESP3 when timeout is reached, like BZPOPMIN/BZPOPMAX.

I'm not sure it's wise for ZMPOP to return an empty array when it can't pop, i think it should return NIL like the new LMPOP.
In the case of the existing ZPOP, these return an array of 0 or more pairs, so maybe an empty array is ok.
but for ZMPOP, it returns a stricture containing key name and a list of pair, so i think this makes it more similar to BZPOP and LMPOP. i.e the response is an invalid one, not an empty list.
@itamarhaber WDYT?

Copy link
Member

@oranagra oranagra left a comment

Choose a reason for hiding this comment

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

looks good. obviously missing tests..

@oranagra oranagra added release-notes indication that this issue needs to be mentioned in the release notes state:major-decision Requires core team consensus state:needs-doc-pr requires a PR to redis-doc repository state:needs-test-code the PR is missing test code labels Sep 12, 2021
Co-authored-by: Oran Agra <[email protected]>
Copy link
Member

@oranagra oranagra left a comment

Choose a reason for hiding this comment

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

changes LGTM

Copy link
Contributor

@madolson madolson left a comment

Choose a reason for hiding this comment

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

API looks good, this looks like it still needs tests as Oran mentioned.

@enjoy-binbin
Copy link
Contributor Author

Look like i added a bunch of test code again...

Copy link
Member

@oranagra oranagra left a comment

Choose a reason for hiding this comment

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

@redis/core-team please approve the new commands.
@enjoy-binbin please make a redis-doc PR

@oranagra
Copy link
Member

oranagra commented Sep 19, 2021

triggered a partial CI on all platforms: https://github.com/redis/redis/actions/runs/1250894823
valgrind and all platforms passed: (--single integration/aof --single unit/type/list --single unit/type/zset)

@oranagra oranagra added approval-needed Waiting for core team approval to be merged state:to-be-merged The PR should be merged soon, even if not yet ready, this is used so that it won't be forgotten and removed state:needs-test-code the PR is missing test code labels Sep 19, 2021
@oranagra oranagra merged commit 14d6abd into redis:unstable Sep 23, 2021
@enjoy-binbin enjoy-binbin deleted the add_zmpop_bzmpop branch September 23, 2021 06:04
enjoy-binbin added a commit to enjoy-binbin/redis that referenced this pull request Oct 31, 2021
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.
oranagra pushed a commit that referenced this pull request Oct 31, 2021
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 #9373, ZMPOP/BZMPOP introduced in #9484.
enjoy-binbin added a commit to enjoy-binbin/redis that referenced this pull request May 23, 2022
This bug was introduced in redis#9484 (7.0.0).
It result that BZMPOP blocked on non-key arguments.

Like `bzmpop 0 1 myzset min count 10`, this command will additionally
block in these keys (except for the first and the last argument):
- 0: timeout value
- 1: numkeys value
- min: min/max token
- count: count token

Fixes redis#10762
oranagra pushed a commit that referenced this pull request May 23, 2022
This bug was introduced in #9484 (7.0.0).
It result that BZMPOP blocked on non-key arguments.

Like `bzmpop 0 1 myzset min count 10`, this command will additionally
block in these keys (except for the first and the last argument) and can return their values:
- 0: timeout value
- 1: numkeys value
- min: min/max token
- count: count token
enjoy-binbin added a commit to enjoy-binbin/redis that referenced this pull request Jul 31, 2023
This bug was introduced in redis#9484 (7.0.0).
It result that BZMPOP blocked on non-key arguments.

Like `bzmpop 0 1 myzset min count 10`, this command will additionally
block in these keys (except for the first and the last argument) and can return their values:
- 0: timeout value
- 1: numkeys value
- min: min/max token
- count: count token
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval-needed Waiting for core team approval to be merged release-notes indication that this issue needs to be mentioned in the release notes state:major-decision Requires core team consensus state:needs-doc-pr requires a PR to redis-doc repository state:to-be-merged The PR should be merged soon, even if not yet ready, this is used so that it won't be forgotten

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants