Fix blocking operations from missing new lists

Behrad Zari discovered [1] and Josiah reported [2]: if you block
and wait for a list to exist, but the list creates from
a non-push command, the blocked client never gets notified.

This commit adds notification of blocked clients into
the DB layer and away from individual commands.

Lists can be created by [LR]PUSH, SORT..STORE, RENAME, MOVE,
and RESTORE.  Previously, blocked client notifications were
only triggered by [LR]PUSH.  Your client would never get
notified if a list were created by SORT..STORE or RENAME or
a RESTORE, etc.

Blocked client notification now happens in one unified place:
  - dbAdd() triggers notification when adding a list to the DB

Two new tests are added that fail prior to this commit.

All test pass.

Fixes #1668

[1]: https://groups.google.com/forum/#!topic/redis-db/k4oWfMkN1NU
[2]: #1668
This commit is contained in:
Matt Stancliff
2014-04-07 21:22:30 -04:00
committed by antirez
parent 8b059f06d7
commit 7fc1fc8ca7
4 changed files with 30 additions and 11 deletions

View File

@ -408,6 +408,29 @@ start_server {
$rd read
} {}
test "BLPOP when new key is moved into place" {
set rd [redis_deferring_client]
$rd blpop foo 5
r lpush bob abc def hij
r rename bob foo
$rd read
} {foo hij}
test "BLPOP when result key is created by SORT..STORE" {
set rd [redis_deferring_client]
# zero out list from previous test without explicit delete
r lpop foo
r lpop foo
r lpop foo
$rd blpop foo 5
r lpush notfoo hello hola aguacate konichiwa zanzibar
r sort notfoo ALPHA store foo
$rd read
} {foo aguacate}
foreach {pop} {BLPOP BRPOP} {
test "$pop: with single empty list argument" {
set rd [redis_deferring_client]