BZPOPMAX
Introduction
In Dragonfly, as well as in Redis and Valkey, the BZPOPMAX
command is used to remove and return the member with the highest score in a sorted set.
If the sorted set is empty, the command will block the connection for a specified timeout until a member is available to pop.
This makes it particularly useful for creating delayed or sorted workflows such as job queues where items with the highest priority need to be processed first.
If multiple sorted sets are provided, BZPOPMAX
will pop from the first non-empty sorted set encountered in the order that the keys are given.
Syntax
BZPOPMAX key [key ...] timeout
- Time complexity: O(log(N)) with N being the number of elements in the sorted set.
- ACL categories: @write, @sortedset, @fast, @blocking
Parameter Explanations
key
: One or more keys, each representing a sorted set.timeout
: The maximum number of seconds to wait if all the provided sorted sets are empty. A0
timeout means to block indefinitely until an element is available to pop.
Return Values
The command returns a three-element array containing:
- The name of the sorted set that the element was popped from.
- The element with the highest score.
- The score itself.
If the timeout expires without any elements to pop, nil
is returned.
Code Examples
Basic Example
Pop the highest score element from a sorted set:
dragonfly$> ZADD myzset 1 "item1" 2 "item2" 3 "item3"
(integer) 3
dragonfly$> BZPOPMAX myzset 0
1) "myzset"
2) "item3"
3) "3"
Blocking for Elements
If the sorted set is empty, BZPOPMAX
will wait for new elements or until the timeout:
dragonfly$> ZADD myzset 1 "item1" 2 "item2"
(integer) 2
dragonfly$> ZPOPMAX myzset
1) "item2"
2) "2"
dragonfly$> ZPOPMAX myzset
1) "item1"
2) "1"
dragonfly$> BZPOPMAX myzset 5
(nil) # No elements in the sorted set, waited for 5 seconds and then returned nil.
Using Multiple Keys
You can specify multiple sorted sets. The command will act on the first non-empty set encountered:
dragonfly$> ZADD zset1 1 "a" 2 "b"
(integer) 2
dragonfly$> ZADD zset2 1 "x" 3 "y"
(integer) 2
dragonfly$> BZPOPMAX zset1 zset2 0
1) "zset1" # Even though 'zset2' has a higher score, 'zset1' is popped first because it was specified first.
2) "b"
3) "2"
Indefinite Blocking
By setting the timeout
value to 0
, the connection will block indefinitely until a new element can be popped:
dragonfly$> BZPOPMAX somezset 0
# The connection will block until a new element is added to 'somezset'.
Best Practices
- Use
BZPOPMAX
for priority job queues, where tasks with higher scores (priority) must be processed first. - Set a reasonable timeout to avoid blocking connections permanently unless you specifically need indefinite blocking.
Common Mistakes
- Using
BZPOPMAX
on non-sorted set types can result in an error. Ensure that you only use this command on sorted sets. - Assuming this command will pop values from other types like lists; use other blocking list commands such as
BLPOP
orBRPOP
in those cases. - It's easy to confuse the timeout parameter with key names if you're not careful with the syntax.
FAQs
What happens if the timeout is set to zero?
If the timeout is set to 0
, the connection will block indefinitely until a new element can be popped from the sorted set(s).
Can I block on multiple sorted sets?
Yes, BZPOPMAX
accepts multiple sorted set keys and will pop from the first non-empty sorted set, going through the list of keys from left to right, in the order they are provided.
What is the typical use case for BZPOPMAX
?
BZPOPMAX
is often used in priority queues, where jobs with higher priority (indicated by score) need to be processed as soon as they are available. If no jobs exist, the command waits for new ones.