Dispatcher for keyspace notifications to module subscriber functions. * This gets called only if at least one module requested to be notified on * keyspace notifications */
| 6110 | * This gets called only if at least one module requested to be notified on |
| 6111 | * keyspace notifications */ |
| 6112 | void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) { |
| 6113 | /* Don't do anything if there aren't any subscribers */ |
| 6114 | if (listLength(moduleKeyspaceSubscribers) == 0) return; |
| 6115 | |
| 6116 | listIter li; |
| 6117 | listNode *ln; |
| 6118 | listRewind(moduleKeyspaceSubscribers,&li); |
| 6119 | |
| 6120 | /* Remove irrelevant flags from the type mask */ |
| 6121 | type &= ~(NOTIFY_KEYEVENT | NOTIFY_KEYSPACE); |
| 6122 | |
| 6123 | while((ln = listNext(&li))) { |
| 6124 | RedisModuleKeyspaceSubscriber *sub = (RedisModuleKeyspaceSubscriber*)ln->value; |
| 6125 | /* Only notify subscribers on events matching they registration, |
| 6126 | * and avoid subscribers triggering themselves */ |
| 6127 | if ((sub->event_mask & type) && sub->active == 0) { |
| 6128 | RedisModuleCtx ctx = REDISMODULE_CTX_INIT; |
| 6129 | ctx.module = sub->module; |
| 6130 | ctx.client = moduleFreeContextReusedClient; |
| 6131 | selectDb(ctx.client, dbid); |
| 6132 | |
| 6133 | /* mark the handler as active to avoid reentrant loops. |
| 6134 | * If the subscriber performs an action triggering itself, |
| 6135 | * it will not be notified about it. */ |
| 6136 | sub->active = 1; |
| 6137 | sub->notify_callback(&ctx, type, event, key); |
| 6138 | sub->active = 0; |
| 6139 | moduleFreeContext(&ctx); |
| 6140 | } |
| 6141 | } |
| 6142 | } |
| 6143 | |
| 6144 | /* Unsubscribe any notification subscribers this module has upon unloading */ |
| 6145 | void moduleUnsubscribeNotifications(RedisModule *module) { |
no test coverage detected