Skip to content

Commit 39ec5a3

Browse files
authored
DEV: fix bug on BLPOP command page (#2422)
1 parent a491dcf commit 39ec5a3

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

content/commands/blpop.md

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,45 @@ specified keys.
9999

100100
## What key is served first? What client? What element? Priority ordering details.
101101

102-
* If the client tries to blocks for multiple keys, but at least one key contains elements, the returned key / element pair is the first key from left to right that has one or more elements. In this case the client is not blocked. So for instance `BLPOP key1 key2 key3 key4 0`, assuming that both `key2` and `key4` are non-empty, will always return an element from `key2`.
103-
* If multiple clients are blocked for the same key, the first client to be served is the one that was waiting for more time (the first that blocked for the key). Once a client is unblocked it does not retain any priority, when it blocks again with the next call to `BLPOP` it will be served accordingly to the number of clients already blocked for the same key, that will all be served before it (from the first to the last that blocked).
104-
* When a client is blocking for multiple keys at the same time, and elements are available at the same time in multiple keys (because of a transaction or a Lua script added elements to multiple lists), the client will be unblocked using the first key that received a push operation (assuming it has enough elements to serve our client, as there may be other clients as well waiting for this key). Basically after the execution of every command Redis will run a list of all the keys that received data AND that have at least a client blocked. The list is ordered by new element arrival time, from the first key that received data to the last. For every key processed, Redis will serve all the clients waiting for that key in a FIFO fashion, as long as there are elements in this key. When the key is empty or there are no longer clients waiting for this key, the next key that received new data in the previous command / transaction / script is processed, and so forth.
102+
* If the client tries to block for multiple keys, but at least one key contains elements, the returned key/element pair is the first key from left to right that has one or more elements. In this case, the client is not blocked. For example, `BLPOP key1 key2 key3 key4 0`, assuming that both `key2` and `key4` are non-empty, will always return an element from `key2`.
103+
104+
* If multiple clients are blocked for the same key, the first client to be served is the one that has been waiting the longest (the first that blocked for the key). Once a client is unblocked it does not retain any priority; when it blocks again with another `BLPOP` call, it will be served according to its new position in the queue.
105+
106+
* When a client is blocking for multiple keys and multiple keys become non-empty as a result of the same command, transaction, or Lua script, the client is served according to the **order of keys in its `BLPOP` call**, not the order of the write operations. After the writes occur, Redis reprocesses the blocking command for the client and pops from the **first non-empty key** in the key list.
107+
For example, a client blocked on `BLPOP key1 key2 0` will pop from `key1` if both `key1` and `key2` receive elements during the same `MULTI`/`EXEC` transaction, because `key1` appears first.
108+
109+
Internally, when a write makes progress possible for a blocked client, Redis marks that client as unblocked (adding it to an internal queue). No reply is sent immediately. Before the server goes idle (in the `beforeSleep()` phase), Redis rechecks the blocking command and serves the client based on the first non-empty key in its provided key list.
110+
111+
#### Example
112+
113+
**Client A**
114+
115+
```
116+
BLPOP key1 key2 0
117+
```
118+
119+
**Client B**
120+
121+
```
122+
MULTI
123+
RPUSH key2 1 2 3 4
124+
RPUSH key1 5 6 7
125+
EXEC
126+
```
127+
128+
Although `key2` is pushed first inside the transaction, Redis reprocesses the blocking command for Client A after the transaction completes.
129+
At that time both lists are non-empty, and `BLPOP` pops from the first non-empty key in its argument list (`key1`):
130+
131+
```
132+
"key1"
133+
"5"
134+
```
135+
136+
To make Redis pop from `key2` instead, reverse the order of the keys in the blocking call:
137+
138+
```
139+
BLPOP key2 key1 0
140+
```
105141

106142
## Behavior of `BLPOP` when multiple elements are pushed inside a list.
107143

content/commands/xreadgroup.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,10 @@ To see how the command actually replies, please check the [`XREAD`]({{< relref "
232232

233233
## What happens when a pending message is deleted?
234234

235-
Entries may be deleted from the stream due to trimming with [`XADD`]({{< relref "/commands/xall" >}}) or [`XTRIM`]({{< relref "/commands/xtrim" >}}),
235+
Entries may be deleted from the stream due to trimming with [`XADD`]({{< relref "/commands/xadd" >}}) or [`XTRIM`]({{< relref "/commands/xtrim" >}}),
236236
or explicit calls to [`XDEL`]({{< relref "/commands/xdel" >}}), [`XDELEX`]({{< relref "/commands/xdelex" >}}), or [`XACKDEL`]({{< relref "/commands/xackdel" >}}).
237237

238-
When an entry is trimmed with [`XADD`]({{< relref "/commands/xall" >}}) or [`XTRIM`]({{< relref "/commands/xtrim" >}}) and `DELREF` or `ACKED` are not specified,
238+
When an entry is trimmed with [`XADD`]({{< relref "/commands/xadd" >}}) or [`XTRIM`]({{< relref "/commands/xtrim" >}}) and `DELREF` or `ACKED` are not specified,
239239
deleted with [`XDEL`]({{< relref "/commands/xdel" >}}), or deleted with [`XDELEX`]({{< relref "/commands/xdelex" >}}) or [`XACKDEL`]({{< relref "/commands/xackdel" >}})
240240
and `DELREF` or `ACKED` are not specified, Redis doesn't prevent the deletion of entries that are present in the stream's PELs.
241241
When this happens, the PELs retain the deleted entries' IDs, but the actual entry payload is no longer available.

0 commit comments

Comments
 (0)