-
Notifications
You must be signed in to change notification settings - Fork 24.5k
Description
Describe the bug
When using RedisModule_BlockClientOnKeys it should be possible to unblock the client by calling RedisModule_SignalKeyAsReady. However this is not working if the call is performed inside the callback of a timer.
The following code reproduces the issue. Note that for RedisModule_SignalKeyAsReady to work at all, the key we are signalling must exist before we call it as reported here (#7878)
#include "redismodule.h"
#include <stdlib.h>
int BlockedReplyCallback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
RedisModule_Log(ctx, "warning", "Reply callback!");
RedisModule_ReplyWithSimpleString(ctx, "We are done!");
return REDISMODULE_OK;
}
int TimeoutReplyCallback(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
RedisModule_Log(ctx, "warning", "Timed out!");
RedisModule_ReplyWithSimpleString(ctx, "Timed Out");
return REDISMODULE_OK;
}
void BlockedFreePrivdata(RedisModuleCtx *ctx, void *privdata) {
RedisModule_Log(ctx, "warning", "Freeing all priv data");
}
void TimerCallback(RedisModuleCtx *ctx, void *data) {
RedisModuleString *key = data;
RedisModule_Call(ctx, "RPUSH", "sc", key, "foobar");
RedisModule_SignalKeyAsReady(ctx, key);
}
int HelloworldRand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
RedisModuleBlockedClient* bc = RedisModule_BlockClientOnKeys(ctx,
BlockedReplyCallback,
TimeoutReplyCallback,
BlockedFreePrivdata,
10000,
&argv[1],
1,
NULL);
RedisModule_HoldString(ctx, argv[1]);
RedisModule_CreateTimer(ctx,
1000,
TimerCallback,
argv[1]);
return REDISMODULE_OK;
}
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
if (RedisModule_Init(ctx,"helloworld",1,REDISMODULE_APIVER_1)
== REDISMODULE_ERR) return REDISMODULE_ERR;
if (RedisModule_CreateCommand(ctx,"bug2",
HelloworldRand_RedisCommand, "",
0, 0, 0) == REDISMODULE_ERR)
return REDISMODULE_ERR;
return REDISMODULE_OK;
}To reproduce
Just compile and load that module in redis, call it with for example "bug2 1234". It should create a list named 1234 with one element "foobar" in it. However the command is not unblocked after 1 second.
Expected behavior
The command should unblock one second after running it.
Additional information
This issue is reproducible with Redis 6.0.8.
Some observations. If the call to RPUSH is moved outside of the timer callback, then the command will unblock the first time it is called, but not the second time (as if it detects the LIST was already there and then ignore the signalling).