Skip to content

Commit

Permalink
Modules: Minor fixes
Browse files Browse the repository at this point in the history
Fix redis#7879 redis#7880

1. Fix some comments
2. Make sure blocked-on-keys client privdata is accessible
   from withing the timeout callback
3. Handle blocked clients in beforeSleep - In case a key
   becomses "ready" outside of processCommand
  • Loading branch information
guybe7 committed Oct 12, 2020
1 parent 8b49788 commit 0b1e1d0
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/blocked.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ void handleClientsBlockedOnKeys(void) {
server.fixed_time_expire++;
updateCachedTime(0);

/* Serve clients blocked on list key. */
/* Serve clients blocked on the key. */
robj *o = lookupKeyWrite(rl->db,rl->key);

if (o != NULL) {
Expand Down
19 changes: 10 additions & 9 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -4638,8 +4638,9 @@ RedisModuleBlockedClient *RM_BlockClientOnKeys(RedisModuleCtx *ctx, RedisModuleC

/* This function is used in order to potentially unblock a client blocked
* on keys with RedisModule_BlockClientOnKeys(). When this function is called,
* all the clients blocked for this key will get their reply callback called,
* and if the callback returns REDISMODULE_OK the client will be unblocked. */
* all the clients blocked for this key will get their reply_callback called.
*
* Note: The function has no effect if the signaled key doesn't exist. */
void RM_SignalKeyAsReady(RedisModuleCtx *ctx, RedisModuleString *key) {
signalKeyAsReady(ctx->client->db, key, OBJ_MODULE);
}
Expand Down Expand Up @@ -4683,14 +4684,12 @@ int moduleClientIsBlockedOnKeys(client *c) {
*
* Note 1: this function can be called from threads spawned by the module.
*
* Note 2: when we unblock a client that is blocked for keys using
* the API RedisModule_BlockClientOnKeys(), the privdata argument here is
* not used, and the reply callback is called with the privdata pointer that
* was passed when blocking the client.
*
* Note 2: when we unblock a client that is blocked for keys using the API
* RedisModule_BlockClientOnKeys(), the privdata argument here is not used.
* Unblocking a client that was blocked for keys using this API will still
* require the client to get some reply, so the function will use the
* "timeout" handler in order to do so. */
* "timeout" handler in order to do so (The privdata provided in
* RedisModule_BlockClientOnKeys() is accessible via . */
int RM_UnblockClient(RedisModuleBlockedClient *bc, void *privdata) {
if (bc->blocked_on_keys) {
/* In theory the user should always pass the timeout handler as an
Expand Down Expand Up @@ -4834,6 +4833,7 @@ void moduleBlockedClientTimedOut(client *c) {
ctx.module = bc->module;
ctx.client = bc->client;
ctx.blocked_client = bc;
ctx.blocked_privdata = bc->privdata;
bc->timeout_callback(&ctx,(void**)c->argv,c->argc);
moduleFreeContext(&ctx);
/* For timeout events, we do not want to call the disconnect callback,
Expand All @@ -4854,7 +4854,8 @@ int RM_IsBlockedTimeoutRequest(RedisModuleCtx *ctx) {
return (ctx->flags & REDISMODULE_CTX_BLOCKED_TIMEOUT) != 0;
}

/* Get the private data set by RedisModule_UnblockClient() */
/* Get the private data set by RedisModule_UnblockClient()
* Note: This API will return NULL if called from within the timeout_callback. */
void *RM_GetBlockedClientPrivateData(RedisModuleCtx *ctx) {
return ctx->blocked_privdata;
}
Expand Down
5 changes: 5 additions & 0 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -2286,6 +2286,11 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
* releasing the GIL. Redis main thread will not touch anything at this
* time. */
if (moduleCount()) moduleReleaseGIL();

/* Try to process blocked clients every once in while. Example: A module
* calls RM_SignalKeyAsReady from within a timer callback (So we don't
* visit processCommand() at all). */
handleClientsBlockedOnKeys();
}

/* This function is called immediately after the event loop multiplexing
Expand Down

0 comments on commit 0b1e1d0

Please sign in to comment.