Dispatcher for keyspace notifications to module subscriber functions. * This gets called only if at least one module requested to be notified on * keyspace notifications */
| 5934 | * This gets called only if at least one module requested to be notified on |
| 5935 | * keyspace notifications */ |
| 5936 | void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) { |
| 5937 | /* Don't do anything if there aren't any subscribers */ |
| 5938 | if (listLength(moduleKeyspaceSubscribers) == 0) return; |
| 5939 | |
| 5940 | listIter li; |
| 5941 | listNode *ln; |
| 5942 | listRewind(moduleKeyspaceSubscribers,&li); |
| 5943 | |
| 5944 | /* Remove irrelevant flags from the type mask */ |
| 5945 | type &= ~(NOTIFY_KEYEVENT | NOTIFY_KEYSPACE); |
| 5946 | |
| 5947 | while((ln = listNext(&li))) { |
| 5948 | RedisModuleKeyspaceSubscriber *sub = ln->value; |
| 5949 | /* Only notify subscribers on events matching they registration, |
| 5950 | * and avoid subscribers triggering themselves */ |
| 5951 | if ((sub->event_mask & type) && sub->active == 0) { |
| 5952 | RedisModuleCtx ctx = REDISMODULE_CTX_INIT; |
| 5953 | ctx.module = sub->module; |
| 5954 | ctx.client = moduleFreeContextReusedClient; |
| 5955 | selectDb(ctx.client, dbid); |
| 5956 | |
| 5957 | /* mark the handler as active to avoid reentrant loops. |
| 5958 | * If the subscriber performs an action triggering itself, |
| 5959 | * it will not be notified about it. */ |
| 5960 | sub->active = 1; |
| 5961 | sub->notify_callback(&ctx, type, event, key); |
| 5962 | sub->active = 0; |
| 5963 | moduleFreeContext(&ctx); |
| 5964 | } |
| 5965 | } |
| 5966 | } |
| 5967 | |
| 5968 | /* Unsubscribe any notification subscribers this module has upon unloading */ |
| 5969 | void moduleUnsubscribeNotifications(RedisModule *module) { |
no test coverage detected