summaryrefslogtreecommitdiff
path: root/src/blocked.c
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2019-10-31 12:23:55 +0100
committerantirez <antirez@gmail.com>2019-10-31 12:23:55 +0100
commit66f55bc5c15d72542983f37c6c1b48b0c1618917 (patch)
tree769af6fe7ab147e80a4a6f00bb6700993b8ff198 /src/blocked.c
parent629081f839498734d3426d71653619d4f9e93dc9 (diff)
downloadredis-66f55bc5c15d72542983f37c6c1b48b0c1618917.tar.gz
Modules: block on keys: fix bugs in processing order.
Diffstat (limited to 'src/blocked.c')
-rw-r--r--src/blocked.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/blocked.c b/src/blocked.c
index fb58f850b..3110c00fc 100644
--- a/src/blocked.c
+++ b/src/blocked.c
@@ -450,6 +450,22 @@ void serveClientsBlockedOnKeyByModule(readyList *rl) {
listNode *clientnode = listFirst(clients);
client *receiver = clientnode->value;
+ /* Put at the tail, so that at the next call
+ * we'll not run into it again: clients here may not be
+ * ready to be served, so they'll remain in the list
+ * sometimes. We want also be able to skip clients that are
+ * not blocked for the MODULE type safely. */
+ listDelNode(clients,clientnode);
+ listAddNodeTail(clients,receiver);
+
+ if (receiver->btype != BLOCKED_MODULE) continue;
+
+ /* Note that if *this* client cannot be served by this key,
+ * it does not mean that another client that is next into the
+ * list cannot be served as well: they may be blocked by
+ * different modules with different triggers to consider if a key
+ * is ready or not. This means we can't exit the loop but need
+ * to continue after the first failure. */
if (!moduleTryServeClientBlockedOnKey(receiver, rl->key)) continue;
moduleUnblockClient(receiver);