Commit f27a6423 authored by Dvir Volk's avatar Dvir Volk
Browse files

Use one static client for all keyspace notification callbacks

parent 3aab1241
...@@ -235,6 +235,9 @@ typedef struct RedisModuleKeyspaceSubscriber { ...@@ -235,6 +235,9 @@ typedef struct RedisModuleKeyspaceSubscriber {
/* The module keyspace notification subscribers list */ /* The module keyspace notification subscribers list */
static list *moduleKeyspaceSubscribers; static list *moduleKeyspaceSubscribers;
/* Static client recycled for all notification clients, to avoid allocating per round. */
static client *moduleKeyspaceSubscribersClient;
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
* Prototypes * Prototypes
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
...@@ -3769,10 +3772,6 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) ...@@ -3769,10 +3772,6 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid)
/* Remove irrelevant flags from the type mask */ /* Remove irrelevant flags from the type mask */
type &= ~(NOTIFY_KEYEVENT | NOTIFY_KEYSPACE); type &= ~(NOTIFY_KEYEVENT | NOTIFY_KEYSPACE);
/* Setup a fake client, so we can have proper db selection when performing
* actions. We use one client for all handlers, writing to it will crash */
client *c = createClient(-1);
c->flags |= CLIENT_MODULE;
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
RedisModuleKeyspaceSubscriber *sub = ln->value; RedisModuleKeyspaceSubscriber *sub = ln->value;
...@@ -3781,8 +3780,9 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) ...@@ -3781,8 +3780,9 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid)
if ((sub->event_mask & type) && sub->active == 0) { if ((sub->event_mask & type) && sub->active == 0) {
RedisModuleCtx ctx = REDISMODULE_CTX_INIT; RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
ctx.module = sub->module; ctx.module = sub->module;
selectDb(c, dbid); ctx.client = moduleKeyspaceSubscribersClient;
ctx.client = c; selectDb(ctx.client, dbid);
/* mark the handler as activer to avoid reentrant loops. /* mark the handler as activer to avoid reentrant loops.
* If the subscriber performs an action triggering itself, * If the subscriber performs an action triggering itself,
* it will not be notified about it. */ * it will not be notified about it. */
...@@ -3792,7 +3792,7 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) ...@@ -3792,7 +3792,7 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid)
moduleFreeContext(&ctx); moduleFreeContext(&ctx);
} }
} }
freeClient(c);
} }
/* Unsubscribe any notification subscirbers this module has upon unloading */ /* Unsubscribe any notification subscirbers this module has upon unloading */
...@@ -3850,7 +3850,11 @@ void moduleInitModulesSystem(void) { ...@@ -3850,7 +3850,11 @@ void moduleInitModulesSystem(void) {
server.loadmodule_queue = listCreate(); server.loadmodule_queue = listCreate();
modules = dictCreate(&modulesDictType,NULL); modules = dictCreate(&modulesDictType,NULL);
/* Set up the keyspace notification susbscriber list and static client */
moduleKeyspaceSubscribers = listCreate(); moduleKeyspaceSubscribers = listCreate();
moduleKeyspaceSubscribersClient = createClient(-1);
moduleKeyspaceSubscribersClient->flags |= CLIENT_MODULE;
moduleRegisterCoreAPI(); moduleRegisterCoreAPI();
if (pipe(server.module_blocked_pipe) == -1) { if (pipe(server.module_blocked_pipe) == -1) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment