1 /*
2 * Copyright (c) 2016, Salvatore Sanfilippo <antirez at gmail dot com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Redis nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without
15 * specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "server.h"
31 #include "cluster.h"
32 #include "rdb.h"
33 #include <dlfcn.h>
34 #include <sys/stat.h>
35 #include <sys/wait.h>
36
37 /* --------------------------------------------------------------------------
38 * Private data structures used by the modules system. Those are data
39 * structures that are never exposed to Redis Modules, if not as void
40 * pointers that have an API the module can call with them)
41 * -------------------------------------------------------------------------- */
42
43 typedef struct RedisModuleInfoCtx {
44 struct RedisModule *module;
45 const char *requested_section;
46 sds info; /* info string we collected so far */
47 int sections; /* number of sections we collected so far */
48 int in_section; /* indication if we're in an active section or not */
49 int in_dict_field; /* indication that we're currently appending to a dict */
50 } RedisModuleInfoCtx;
51
52 typedef void (*RedisModuleInfoFunc)(RedisModuleInfoCtx *ctx, int for_crash_report);
53
54 /* This structure represents a module inside the system. */
55 struct RedisModule {
56 void *handle; /* Module dlopen() handle. */
57 char *name; /* Module name. */
58 int ver; /* Module version. We use just progressive integers. */
59 int apiver; /* Module API version as requested during initialization.*/
60 list *types; /* Module data types. */
61 list *usedby; /* List of modules using APIs from this one. */
62 list *using; /* List of modules we use some APIs of. */
63 list *filters; /* List of filters the module has registered. */
64 int in_call; /* RM_Call() nesting level */
65 int in_hook; /* Hooks callback nesting level for this module (0 or 1). */
66 int options; /* Module options and capabilities. */
67 int blocked_clients; /* Count of RedisModuleBlockedClient in this module. */
68 RedisModuleInfoFunc info_cb; /* Callback for module to add INFO fields. */
69 };
70 typedef struct RedisModule RedisModule;
71
72 /* This represents a shared API. Shared APIs will be used to populate
73 * the server.sharedapi dictionary, mapping names of APIs exported by
74 * modules for other modules to use, to their structure specifying the
75 * function pointer that can be called. */
76 struct RedisModuleSharedAPI {
77 void *func;
78 RedisModule *module;
79 };
80 typedef struct RedisModuleSharedAPI RedisModuleSharedAPI;
81
82 static dict *modules; /* Hash table of modules. SDS -> RedisModule ptr.*/
83
84 /* Entries in the context->amqueue array, representing objects to free
85 * when the callback returns. */
86 struct AutoMemEntry {
87 void *ptr;
88 int type;
89 };
90
91 /* AutMemEntry type field values. */
92 #define REDISMODULE_AM_KEY 0
93 #define REDISMODULE_AM_STRING 1
94 #define REDISMODULE_AM_REPLY 2
95 #define REDISMODULE_AM_FREED 3 /* Explicitly freed by user already. */
96 #define REDISMODULE_AM_DICT 4
97 #define REDISMODULE_AM_INFO 5
98
99 /* The pool allocator block. Redis Modules can allocate memory via this special
100 * allocator that will automatically release it all once the callback returns.
101 * This means that it can only be used for ephemeral allocations. However
102 * there are two advantages for modules to use this API:
103 *
104 * 1) The memory is automatically released when the callback returns.
105 * 2) This allocator is faster for many small allocations since whole blocks
106 * are allocated, and small pieces returned to the caller just advancing
107 * the index of the allocation.
108 *
109 * Allocations are always rounded to the size of the void pointer in order
110 * to always return aligned memory chunks. */
111
112 #define REDISMODULE_POOL_ALLOC_MIN_SIZE (1024*8)
113 #define REDISMODULE_POOL_ALLOC_ALIGN (sizeof(void*))
114
115 typedef struct RedisModulePoolAllocBlock {
116 uint32_t size;
117 uint32_t used;
118 struct RedisModulePoolAllocBlock *next;
119 char memory[];
120 } RedisModulePoolAllocBlock;
121
122 /* This structure represents the context in which Redis modules operate.
123 * Most APIs module can access, get a pointer to the context, so that the API
124 * implementation can hold state across calls, or remember what to free after
125 * the call and so forth.
126 *
127 * Note that not all the context structure is always filled with actual values
128 * but only the fields needed in a given context. */
129
130 struct RedisModuleBlockedClient;
131
132 struct RedisModuleCtx {
133 void *getapifuncptr; /* NOTE: Must be the first field. */
134 struct RedisModule *module; /* Module reference. */
135 client *client; /* Client calling a command. */
136 struct RedisModuleBlockedClient *blocked_client; /* Blocked client for
137 thread safe context. */
138 struct AutoMemEntry *amqueue; /* Auto memory queue of objects to free. */
139 int amqueue_len; /* Number of slots in amqueue. */
140 int amqueue_used; /* Number of used slots in amqueue. */
141 int flags; /* REDISMODULE_CTX_... flags. */
142 void **postponed_arrays; /* To set with RM_ReplySetArrayLength(). */
143 int postponed_arrays_count; /* Number of entries in postponed_arrays. */
144 void *blocked_privdata; /* Privdata set when unblocking a client. */
145 RedisModuleString *blocked_ready_key; /* Key ready when the reply callback
146 gets called for clients blocked
147 on keys. */
148
149 /* Used if there is the REDISMODULE_CTX_KEYS_POS_REQUEST flag set. */
150 getKeysResult *keys_result;
151
152 struct RedisModulePoolAllocBlock *pa_head;
153 redisOpArray saved_oparray; /* When propagating commands in a callback
154 we reallocate the "also propagate" op
155 array. Here we save the old one to
156 restore it later. */
157 };
158 typedef struct RedisModuleCtx RedisModuleCtx;
159
160 #define REDISMODULE_CTX_INIT {(void*)(unsigned long)&RM_GetApi, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL, {0}}
161 #define REDISMODULE_CTX_MULTI_EMITTED (1<<0)
162 #define REDISMODULE_CTX_AUTO_MEMORY (1<<1)
163 #define REDISMODULE_CTX_KEYS_POS_REQUEST (1<<2)
164 #define REDISMODULE_CTX_BLOCKED_REPLY (1<<3)
165 #define REDISMODULE_CTX_BLOCKED_TIMEOUT (1<<4)
166 #define REDISMODULE_CTX_THREAD_SAFE (1<<5)
167 #define REDISMODULE_CTX_BLOCKED_DISCONNECTED (1<<6)
168 #define REDISMODULE_CTX_MODULE_COMMAND_CALL (1<<7)
169
170 /* This represents a Redis key opened with RM_OpenKey(). */
171 struct RedisModuleKey {
172 RedisModuleCtx *ctx;
173 redisDb *db;
174 robj *key; /* Key name object. */
175 robj *value; /* Value object, or NULL if the key was not found. */
176 void *iter; /* Iterator. */
177 int mode; /* Opening mode. */
178
179 /* Zset iterator. */
180 uint32_t ztype; /* REDISMODULE_ZSET_RANGE_* */
181 zrangespec zrs; /* Score range. */
182 zlexrangespec zlrs; /* Lex range. */
183 uint32_t zstart; /* Start pos for positional ranges. */
184 uint32_t zend; /* End pos for positional ranges. */
185 void *zcurrent; /* Zset iterator current node. */
186 int zer; /* Zset iterator end reached flag
187 (true if end was reached). */
188 };
189 typedef struct RedisModuleKey RedisModuleKey;
190
191 /* RedisModuleKey 'ztype' values. */
192 #define REDISMODULE_ZSET_RANGE_NONE 0 /* This must always be 0. */
193 #define REDISMODULE_ZSET_RANGE_LEX 1
194 #define REDISMODULE_ZSET_RANGE_SCORE 2
195 #define REDISMODULE_ZSET_RANGE_POS 3
196
197 /* Function pointer type of a function representing a command inside
198 * a Redis module. */
199 struct RedisModuleBlockedClient;
200 typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, void **argv, int argc);
201 typedef void (*RedisModuleDisconnectFunc) (RedisModuleCtx *ctx, struct RedisModuleBlockedClient *bc);
202
203 /* This struct holds the information about a command registered by a module.*/
204 struct RedisModuleCommandProxy {
205 struct RedisModule *module;
206 RedisModuleCmdFunc func;
207 struct redisCommand *rediscmd;
208 };
209 typedef struct RedisModuleCommandProxy RedisModuleCommandProxy;
210
211 #define REDISMODULE_REPLYFLAG_NONE 0
212 #define REDISMODULE_REPLYFLAG_TOPARSE (1<<0) /* Protocol must be parsed. */
213 #define REDISMODULE_REPLYFLAG_NESTED (1<<1) /* Nested reply object. No proto
214 or struct free. */
215
216 /* Reply of RM_Call() function. The function is filled in a lazy
217 * way depending on the function called on the reply structure. By default
218 * only the type, proto and protolen are filled. */
219 typedef struct RedisModuleCallReply {
220 RedisModuleCtx *ctx;
221 int type; /* REDISMODULE_REPLY_... */
222 int flags; /* REDISMODULE_REPLYFLAG_... */
223 size_t len; /* Len of strings or num of elements of arrays. */
224 char *proto; /* Raw reply protocol. An SDS string at top-level object. */
225 size_t protolen;/* Length of protocol. */
226 union {
227 const char *str; /* String pointer for string and error replies. This
228 does not need to be freed, always points inside
229 a reply->proto buffer of the reply object or, in
230 case of array elements, of parent reply objects. */
231 long long ll; /* Reply value for integer reply. */
232 struct RedisModuleCallReply *array; /* Array of sub-reply elements. */
233 } val;
234 } RedisModuleCallReply;
235
236 /* Structure representing a blocked client. We get a pointer to such
237 * an object when blocking from modules. */
238 typedef struct RedisModuleBlockedClient {
239 client *client; /* Pointer to the blocked client. or NULL if the client
240 was destroyed during the life of this object. */
241 RedisModule *module; /* Module blocking the client. */
242 RedisModuleCmdFunc reply_callback; /* Reply callback on normal completion.*/
243 RedisModuleCmdFunc timeout_callback; /* Reply callback on timeout. */
244 RedisModuleDisconnectFunc disconnect_callback; /* Called on disconnection.*/
245 void (*free_privdata)(RedisModuleCtx*,void*);/* privdata cleanup callback.*/
246 void *privdata; /* Module private data that may be used by the reply
247 or timeout callback. It is set via the
248 RedisModule_UnblockClient() API. */
249 client *reply_client; /* Fake client used to accumulate replies
250 in thread safe contexts. */
251 int dbid; /* Database number selected by the original client. */
252 int blocked_on_keys; /* If blocked via RM_BlockClientOnKeys(). */
253 int unblocked; /* Already on the moduleUnblocked list. */
254 } RedisModuleBlockedClient;
255
256 static pthread_mutex_t moduleUnblockedClientsMutex = PTHREAD_MUTEX_INITIALIZER;
257 static list *moduleUnblockedClients;
258
259 /* We need a mutex that is unlocked / relocked in beforeSleep() in order to
260 * allow thread safe contexts to execute commands at a safe moment. */
261 static pthread_mutex_t moduleGIL = PTHREAD_MUTEX_INITIALIZER;
262
263
264 /* Function pointer type for keyspace event notification subscriptions from modules. */
265 typedef int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
266
267 /* Keyspace notification subscriber information.
268 * See RM_SubscribeToKeyspaceEvents() for more information. */
269 typedef struct RedisModuleKeyspaceSubscriber {
270 /* The module subscribed to the event */
271 RedisModule *module;
272 /* Notification callback in the module*/
273 RedisModuleNotificationFunc notify_callback;
274 /* A bit mask of the events the module is interested in */
275 int event_mask;
276 /* Active flag set on entry, to avoid reentrant subscribers
277 * calling themselves */
278 int active;
279 } RedisModuleKeyspaceSubscriber;
280
281 /* The module keyspace notification subscribers list */
282 static list *moduleKeyspaceSubscribers;
283
284 /* Static client recycled for when we need to provide a context with a client
285 * in a situation where there is no client to provide. This avoidsallocating
286 * a new client per round. For instance this is used in the keyspace
287 * notifications, timers and cluster messages callbacks. */
288 static client *moduleFreeContextReusedClient;
289
290 /* Data structures related to the exported dictionary data structure. */
291 typedef struct RedisModuleDict {
292 rax *rax; /* The radix tree. */
293 } RedisModuleDict;
294
295 typedef struct RedisModuleDictIter {
296 RedisModuleDict *dict;
297 raxIterator ri;
298 } RedisModuleDictIter;
299
300 typedef struct RedisModuleCommandFilterCtx {
301 RedisModuleString **argv;
302 int argc;
303 } RedisModuleCommandFilterCtx;
304
305 typedef void (*RedisModuleCommandFilterFunc) (RedisModuleCommandFilterCtx *filter);
306
307 typedef struct RedisModuleCommandFilter {
308 /* The module that registered the filter */
309 RedisModule *module;
310 /* Filter callback function */
311 RedisModuleCommandFilterFunc callback;
312 /* REDISMODULE_CMDFILTER_* flags */
313 int flags;
314 } RedisModuleCommandFilter;
315
316 /* Registered filters */
317 static list *moduleCommandFilters;
318
319 typedef void (*RedisModuleForkDoneHandler) (int exitcode, int bysignal, void *user_data);
320
321 static struct RedisModuleForkInfo {
322 RedisModuleForkDoneHandler done_handler;
323 void* done_handler_user_data;
324 } moduleForkInfo = {0};
325
326 typedef struct RedisModuleServerInfoData {
327 rax *rax; /* parsed info data. */
328 } RedisModuleServerInfoData;
329
330 /* Flags for moduleCreateArgvFromUserFormat(). */
331 #define REDISMODULE_ARGV_REPLICATE (1<<0)
332 #define REDISMODULE_ARGV_NO_AOF (1<<1)
333 #define REDISMODULE_ARGV_NO_REPLICAS (1<<2)
334
335 /* Determine whether Redis should signalModifiedKey implicitly.
336 * In case 'ctx' has no 'module' member (and therefore no module->options),
337 * we assume default behavior, that is, Redis signals.
338 * (see RM_GetThreadSafeContext) */
339 #define SHOULD_SIGNAL_MODIFIED_KEYS(ctx) \
340 ctx->module? !(ctx->module->options & REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED) : 1
341
342 /* Server events hooks data structures and defines: this modules API
343 * allow modules to subscribe to certain events in Redis, such as
344 * the start and end of an RDB or AOF save, the change of role in replication,
345 * and similar other events. */
346
347 typedef struct RedisModuleEventListener {
348 RedisModule *module;
349 RedisModuleEvent event;
350 RedisModuleEventCallback callback;
351 } RedisModuleEventListener;
352
353 list *RedisModule_EventListeners; /* Global list of all the active events. */
354 unsigned long long ModulesInHooks = 0; /* Total number of modules in hooks
355 callbacks right now. */
356
357 /* Data structures related to the redis module users */
358
359 /* This callback type is called by moduleNotifyUserChanged() every time
360 * a user authenticated via the module API is associated with a different
361 * user or gets disconnected. */
362 typedef void (*RedisModuleUserChangedFunc) (uint64_t client_id, void *privdata);
363
364 /* This is the object returned by RM_CreateModuleUser(). The module API is
365 * able to create users, set ACLs to such users, and later authenticate
366 * clients using such newly created users. */
367 typedef struct RedisModuleUser {
368 user *user; /* Reference to the real redis user */
369 } RedisModuleUser;
370
371
372 /* --------------------------------------------------------------------------
373 * Prototypes
374 * -------------------------------------------------------------------------- */
375
376 void RM_FreeCallReply(RedisModuleCallReply *reply);
377 void RM_CloseKey(RedisModuleKey *key);
378 void autoMemoryCollect(RedisModuleCtx *ctx);
379 robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *flags, va_list ap);
380 void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx);
381 void RM_ZsetRangeStop(RedisModuleKey *kp);
382 static void zsetKeyReset(RedisModuleKey *key);
383 void RM_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d);
384 void RM_FreeServerInfo(RedisModuleCtx *ctx, RedisModuleServerInfoData *data);
385
386 /* --------------------------------------------------------------------------
387 * Heap allocation raw functions
388 * -------------------------------------------------------------------------- */
389
390 /* Use like malloc(). Memory allocated with this function is reported in
391 * Redis INFO memory, used for keys eviction according to maxmemory settings
392 * and in general is taken into account as memory allocated by Redis.
393 * You should avoid using malloc(). */
RM_Alloc(size_t bytes)394 void *RM_Alloc(size_t bytes) {
395 return zmalloc(bytes);
396 }
397
398 /* Use like calloc(). Memory allocated with this function is reported in
399 * Redis INFO memory, used for keys eviction according to maxmemory settings
400 * and in general is taken into account as memory allocated by Redis.
401 * You should avoid using calloc() directly. */
RM_Calloc(size_t nmemb,size_t size)402 void *RM_Calloc(size_t nmemb, size_t size) {
403 return zcalloc(nmemb*size);
404 }
405
406 /* Use like realloc() for memory obtained with RedisModule_Alloc(). */
RM_Realloc(void * ptr,size_t bytes)407 void* RM_Realloc(void *ptr, size_t bytes) {
408 return zrealloc(ptr,bytes);
409 }
410
411 /* Use like free() for memory obtained by RedisModule_Alloc() and
412 * RedisModule_Realloc(). However you should never try to free with
413 * RedisModule_Free() memory allocated with malloc() inside your module. */
RM_Free(void * ptr)414 void RM_Free(void *ptr) {
415 zfree(ptr);
416 }
417
418 /* Like strdup() but returns memory allocated with RedisModule_Alloc(). */
RM_Strdup(const char * str)419 char *RM_Strdup(const char *str) {
420 return zstrdup(str);
421 }
422
423 /* --------------------------------------------------------------------------
424 * Pool allocator
425 * -------------------------------------------------------------------------- */
426
427 /* Release the chain of blocks used for pool allocations. */
poolAllocRelease(RedisModuleCtx * ctx)428 void poolAllocRelease(RedisModuleCtx *ctx) {
429 RedisModulePoolAllocBlock *head = ctx->pa_head, *next;
430
431 while(head != NULL) {
432 next = head->next;
433 zfree(head);
434 head = next;
435 }
436 ctx->pa_head = NULL;
437 }
438
439 /* Return heap allocated memory that will be freed automatically when the
440 * module callback function returns. Mostly suitable for small allocations
441 * that are short living and must be released when the callback returns
442 * anyway. The returned memory is aligned to the architecture word size
443 * if at least word size bytes are requested, otherwise it is just
444 * aligned to the next power of two, so for example a 3 bytes request is
445 * 4 bytes aligned while a 2 bytes request is 2 bytes aligned.
446 *
447 * There is no realloc style function since when this is needed to use the
448 * pool allocator is not a good idea.
449 *
450 * The function returns NULL if `bytes` is 0. */
RM_PoolAlloc(RedisModuleCtx * ctx,size_t bytes)451 void *RM_PoolAlloc(RedisModuleCtx *ctx, size_t bytes) {
452 if (bytes == 0) return NULL;
453 RedisModulePoolAllocBlock *b = ctx->pa_head;
454 size_t left = b ? b->size - b->used : 0;
455
456 /* Fix alignment. */
457 if (left >= bytes) {
458 size_t alignment = REDISMODULE_POOL_ALLOC_ALIGN;
459 while (bytes < alignment && alignment/2 >= bytes) alignment /= 2;
460 if (b->used % alignment)
461 b->used += alignment - (b->used % alignment);
462 left = (b->used > b->size) ? 0 : b->size - b->used;
463 }
464
465 /* Create a new block if needed. */
466 if (left < bytes) {
467 size_t blocksize = REDISMODULE_POOL_ALLOC_MIN_SIZE;
468 if (blocksize < bytes) blocksize = bytes;
469 b = zmalloc(sizeof(*b) + blocksize);
470 b->size = blocksize;
471 b->used = 0;
472 b->next = ctx->pa_head;
473 ctx->pa_head = b;
474 }
475
476 char *retval = b->memory + b->used;
477 b->used += bytes;
478 return retval;
479 }
480
481 /* --------------------------------------------------------------------------
482 * Helpers for modules API implementation
483 * -------------------------------------------------------------------------- */
484
485 /* Create an empty key of the specified type. 'kp' must point to a key object
486 * opened for writing where the .value member is set to NULL because the
487 * key was found to be non existing.
488 *
489 * On success REDISMODULE_OK is returned and the key is populated with
490 * the value of the specified type. The function fails and returns
491 * REDISMODULE_ERR if:
492 *
493 * 1) The key is not open for writing.
494 * 2) The key is not empty.
495 * 3) The specified type is unknown.
496 */
moduleCreateEmptyKey(RedisModuleKey * key,int type)497 int moduleCreateEmptyKey(RedisModuleKey *key, int type) {
498 robj *obj;
499
500 /* The key must be open for writing and non existing to proceed. */
501 if (!(key->mode & REDISMODULE_WRITE) || key->value)
502 return REDISMODULE_ERR;
503
504 switch(type) {
505 case REDISMODULE_KEYTYPE_LIST:
506 obj = createQuicklistObject();
507 quicklistSetOptions(obj->ptr, server.list_max_ziplist_size,
508 server.list_compress_depth);
509 break;
510 case REDISMODULE_KEYTYPE_ZSET:
511 obj = createZsetZiplistObject();
512 break;
513 case REDISMODULE_KEYTYPE_HASH:
514 obj = createHashObject();
515 break;
516 default: return REDISMODULE_ERR;
517 }
518 dbAdd(key->db,key->key,obj);
519 key->value = obj;
520 return REDISMODULE_OK;
521 }
522
523 /* This function is called in low-level API implementation functions in order
524 * to check if the value associated with the key remained empty after an
525 * operation that removed elements from an aggregate data type.
526 *
527 * If this happens, the key is deleted from the DB and the key object state
528 * is set to the right one in order to be targeted again by write operations
529 * possibly recreating the key if needed.
530 *
531 * The function returns 1 if the key value object is found empty and is
532 * deleted, otherwise 0 is returned. */
moduleDelKeyIfEmpty(RedisModuleKey * key)533 int moduleDelKeyIfEmpty(RedisModuleKey *key) {
534 if (!(key->mode & REDISMODULE_WRITE) || key->value == NULL) return 0;
535 int isempty;
536 robj *o = key->value;
537
538 switch(o->type) {
539 case OBJ_LIST: isempty = listTypeLength(o) == 0; break;
540 case OBJ_SET: isempty = setTypeSize(o) == 0; break;
541 case OBJ_ZSET: isempty = zsetLength(o) == 0; break;
542 case OBJ_HASH: isempty = hashTypeLength(o) == 0; break;
543 case OBJ_STREAM: isempty = streamLength(o) == 0; break;
544 default: isempty = 0;
545 }
546
547 if (isempty) {
548 dbDelete(key->db,key->key);
549 key->value = NULL;
550 return 1;
551 } else {
552 return 0;
553 }
554 }
555
556 /* --------------------------------------------------------------------------
557 * Service API exported to modules
558 *
559 * Note that all the exported APIs are called RM_<funcname> in the core
560 * and RedisModule_<funcname> in the module side (defined as function
561 * pointers in redismodule.h). In this way the dynamic linker does not
562 * mess with our global function pointers, overriding it with the symbols
563 * defined in the main executable having the same names.
564 * -------------------------------------------------------------------------- */
565
566 /* Lookup the requested module API and store the function pointer into the
567 * target pointer. The function returns REDISMODULE_ERR if there is no such
568 * named API, otherwise REDISMODULE_OK.
569 *
570 * This function is not meant to be used by modules developer, it is only
571 * used implicitly by including redismodule.h. */
RM_GetApi(const char * funcname,void ** targetPtrPtr)572 int RM_GetApi(const char *funcname, void **targetPtrPtr) {
573 dictEntry *he = dictFind(server.moduleapi, funcname);
574 if (!he) return REDISMODULE_ERR;
575 *targetPtrPtr = dictGetVal(he);
576 return REDISMODULE_OK;
577 }
578
579 /* Helper function for when a command callback is called, in order to handle
580 * details needed to correctly replicate commands. */
moduleHandlePropagationAfterCommandCallback(RedisModuleCtx * ctx)581 void moduleHandlePropagationAfterCommandCallback(RedisModuleCtx *ctx) {
582 client *c = ctx->client;
583
584 /* We don't need to do anything here if the context was never used
585 * in order to propagate commands. */
586 if (!(ctx->flags & REDISMODULE_CTX_MULTI_EMITTED)) return;
587
588 if (c->flags & CLIENT_LUA) return;
589
590 /* Handle the replication of the final EXEC, since whatever a command
591 * emits is always wrapped around MULTI/EXEC. */
592 alsoPropagate(server.execCommand,c->db->id,&shared.exec,1,
593 PROPAGATE_AOF|PROPAGATE_REPL);
594
595 /* If this is not a module command context (but is instead a simple
596 * callback context), we have to handle directly the "also propagate"
597 * array and emit it. In a module command call this will be handled
598 * directly by call(). */
599 if (!(ctx->flags & REDISMODULE_CTX_MODULE_COMMAND_CALL) &&
600 server.also_propagate.numops)
601 {
602 for (int j = 0; j < server.also_propagate.numops; j++) {
603 redisOp *rop = &server.also_propagate.ops[j];
604 int target = rop->target;
605 if (target)
606 propagate(rop->cmd,rop->dbid,rop->argv,rop->argc,target);
607 }
608 redisOpArrayFree(&server.also_propagate);
609 /* Restore the previous oparray in case of nexted use of the API. */
610 server.also_propagate = ctx->saved_oparray;
611 /* We're done with saved_oparray, let's invalidate it. */
612 redisOpArrayInit(&ctx->saved_oparray);
613 }
614 }
615
616 /* Free the context after the user function was called. */
moduleFreeContext(RedisModuleCtx * ctx)617 void moduleFreeContext(RedisModuleCtx *ctx) {
618 moduleHandlePropagationAfterCommandCallback(ctx);
619 autoMemoryCollect(ctx);
620 poolAllocRelease(ctx);
621 if (ctx->postponed_arrays) {
622 zfree(ctx->postponed_arrays);
623 ctx->postponed_arrays_count = 0;
624 serverLog(LL_WARNING,
625 "API misuse detected in module %s: "
626 "RedisModule_ReplyWithArray(REDISMODULE_POSTPONED_ARRAY_LEN) "
627 "not matched by the same number of RedisModule_SetReplyArrayLen() "
628 "calls.",
629 ctx->module->name);
630 }
631 if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) freeClient(ctx->client);
632 }
633
634 /* This Redis command binds the normal Redis command invocation with commands
635 * exported by modules. */
RedisModuleCommandDispatcher(client * c)636 void RedisModuleCommandDispatcher(client *c) {
637 RedisModuleCommandProxy *cp = (void*)(unsigned long)c->cmd->getkeys_proc;
638 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
639
640 ctx.flags |= REDISMODULE_CTX_MODULE_COMMAND_CALL;
641 ctx.module = cp->module;
642 ctx.client = c;
643 cp->func(&ctx,(void**)c->argv,c->argc);
644 moduleFreeContext(&ctx);
645
646 /* In some cases processMultibulkBuffer uses sdsMakeRoomFor to
647 * expand the query buffer, and in order to avoid a big object copy
648 * the query buffer SDS may be used directly as the SDS string backing
649 * the client argument vectors: sometimes this will result in the SDS
650 * string having unused space at the end. Later if a module takes ownership
651 * of the RedisString, such space will be wasted forever. Inside the
652 * Redis core this is not a problem because tryObjectEncoding() is called
653 * before storing strings in the key space. Here we need to do it
654 * for the module. */
655 for (int i = 0; i < c->argc; i++) {
656 /* Only do the work if the module took ownership of the object:
657 * in that case the refcount is no longer 1. */
658 if (c->argv[i]->refcount > 1)
659 trimStringObjectIfNeeded(c->argv[i]);
660 }
661 }
662
663 /* This function returns the list of keys, with the same interface as the
664 * 'getkeys' function of the native commands, for module commands that exported
665 * the "getkeys-api" flag during the registration. This is done when the
666 * list of keys are not at fixed positions, so that first/last/step cannot
667 * be used.
668 *
669 * In order to accomplish its work, the module command is called, flagging
670 * the context in a way that the command can recognize this is a special
671 * "get keys" call by calling RedisModule_IsKeysPositionRequest(ctx). */
moduleGetCommandKeysViaAPI(struct redisCommand * cmd,robj ** argv,int argc,getKeysResult * result)672 int moduleGetCommandKeysViaAPI(struct redisCommand *cmd, robj **argv, int argc, getKeysResult *result) {
673 RedisModuleCommandProxy *cp = (void*)(unsigned long)cmd->getkeys_proc;
674 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
675
676 ctx.module = cp->module;
677 ctx.client = NULL;
678 ctx.flags |= REDISMODULE_CTX_KEYS_POS_REQUEST;
679
680 /* Initialize getKeysResult */
681 getKeysPrepareResult(result, MAX_KEYS_BUFFER);
682 ctx.keys_result = result;
683
684 cp->func(&ctx,(void**)argv,argc);
685 /* We currently always use the array allocated by RM_KeyAtPos() and don't try
686 * to optimize for the pre-allocated buffer.
687 */
688 moduleFreeContext(&ctx);
689 return result->numkeys;
690 }
691
692 /* Return non-zero if a module command, that was declared with the
693 * flag "getkeys-api", is called in a special way to get the keys positions
694 * and not to get executed. Otherwise zero is returned. */
RM_IsKeysPositionRequest(RedisModuleCtx * ctx)695 int RM_IsKeysPositionRequest(RedisModuleCtx *ctx) {
696 return (ctx->flags & REDISMODULE_CTX_KEYS_POS_REQUEST) != 0;
697 }
698
699 /* When a module command is called in order to obtain the position of
700 * keys, since it was flagged as "getkeys-api" during the registration,
701 * the command implementation checks for this special call using the
702 * RedisModule_IsKeysPositionRequest() API and uses this function in
703 * order to report keys, like in the following example:
704 *
705 * if (RedisModule_IsKeysPositionRequest(ctx)) {
706 * RedisModule_KeyAtPos(ctx,1);
707 * RedisModule_KeyAtPos(ctx,2);
708 * }
709 *
710 * Note: in the example below the get keys API would not be needed since
711 * keys are at fixed positions. This interface is only used for commands
712 * with a more complex structure. */
RM_KeyAtPos(RedisModuleCtx * ctx,int pos)713 void RM_KeyAtPos(RedisModuleCtx *ctx, int pos) {
714 if (!(ctx->flags & REDISMODULE_CTX_KEYS_POS_REQUEST) || !ctx->keys_result) return;
715 if (pos <= 0) return;
716
717 getKeysResult *res = ctx->keys_result;
718
719 /* Check overflow */
720 if (res->numkeys == res->size) {
721 int newsize = res->size + (res->size > 8192 ? 8192 : res->size);
722 getKeysPrepareResult(res, newsize);
723 }
724
725 res->keys[res->numkeys++] = pos;
726 }
727
728 /* Helper for RM_CreateCommand(). Turns a string representing command
729 * flags into the command flags used by the Redis core.
730 *
731 * It returns the set of flags, or -1 if unknown flags are found. */
commandFlagsFromString(char * s)732 int64_t commandFlagsFromString(char *s) {
733 int count, j;
734 int64_t flags = 0;
735 sds *tokens = sdssplitlen(s,strlen(s)," ",1,&count);
736 for (j = 0; j < count; j++) {
737 char *t = tokens[j];
738 if (!strcasecmp(t,"write")) flags |= CMD_WRITE;
739 else if (!strcasecmp(t,"readonly")) flags |= CMD_READONLY;
740 else if (!strcasecmp(t,"admin")) flags |= CMD_ADMIN;
741 else if (!strcasecmp(t,"deny-oom")) flags |= CMD_DENYOOM;
742 else if (!strcasecmp(t,"deny-script")) flags |= CMD_NOSCRIPT;
743 else if (!strcasecmp(t,"allow-loading")) flags |= CMD_LOADING;
744 else if (!strcasecmp(t,"pubsub")) flags |= CMD_PUBSUB;
745 else if (!strcasecmp(t,"random")) flags |= CMD_RANDOM;
746 else if (!strcasecmp(t,"allow-stale")) flags |= CMD_STALE;
747 else if (!strcasecmp(t,"no-monitor")) flags |= CMD_SKIP_MONITOR;
748 else if (!strcasecmp(t,"no-slowlog")) flags |= CMD_SKIP_SLOWLOG;
749 else if (!strcasecmp(t,"fast")) flags |= CMD_FAST;
750 else if (!strcasecmp(t,"no-auth")) flags |= CMD_NO_AUTH;
751 else if (!strcasecmp(t,"getkeys-api")) flags |= CMD_MODULE_GETKEYS;
752 else if (!strcasecmp(t,"no-cluster")) flags |= CMD_MODULE_NO_CLUSTER;
753 else break;
754 }
755 sdsfreesplitres(tokens,count);
756 if (j != count) return -1; /* Some token not processed correctly. */
757 return flags;
758 }
759
760 /* Register a new command in the Redis server, that will be handled by
761 * calling the function pointer 'func' using the RedisModule calling
762 * convention. The function returns REDISMODULE_ERR if the specified command
763 * name is already busy or a set of invalid flags were passed, otherwise
764 * REDISMODULE_OK is returned and the new command is registered.
765 *
766 * This function must be called during the initialization of the module
767 * inside the RedisModule_OnLoad() function. Calling this function outside
768 * of the initialization function is not defined.
769 *
770 * The command function type is the following:
771 *
772 * int MyCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
773 *
774 * And is supposed to always return REDISMODULE_OK.
775 *
776 * The set of flags 'strflags' specify the behavior of the command, and should
777 * be passed as a C string composed of space separated words, like for
778 * example "write deny-oom". The set of flags are:
779 *
780 * * **"write"**: The command may modify the data set (it may also read
781 * from it).
782 * * **"readonly"**: The command returns data from keys but never writes.
783 * * **"admin"**: The command is an administrative command (may change
784 * replication or perform similar tasks).
785 * * **"deny-oom"**: The command may use additional memory and should be
786 * denied during out of memory conditions.
787 * * **"deny-script"**: Don't allow this command in Lua scripts.
788 * * **"allow-loading"**: Allow this command while the server is loading data.
789 * Only commands not interacting with the data set
790 * should be allowed to run in this mode. If not sure
791 * don't use this flag.
792 * * **"pubsub"**: The command publishes things on Pub/Sub channels.
793 * * **"random"**: The command may have different outputs even starting
794 * from the same input arguments and key values.
795 * * **"allow-stale"**: The command is allowed to run on slaves that don't
796 * serve stale data. Don't use if you don't know what
797 * this means.
798 * * **"no-monitor"**: Don't propagate the command on monitor. Use this if
799 * the command has sensible data among the arguments.
800 * * **"no-slowlog"**: Don't log this command in the slowlog. Use this if
801 * the command has sensible data among the arguments.
802 * * **"fast"**: The command time complexity is not greater
803 * than O(log(N)) where N is the size of the collection or
804 * anything else representing the normal scalability
805 * issue with the command.
806 * * **"getkeys-api"**: The command implements the interface to return
807 * the arguments that are keys. Used when start/stop/step
808 * is not enough because of the command syntax.
809 * * **"no-cluster"**: The command should not register in Redis Cluster
810 * since is not designed to work with it because, for
811 * example, is unable to report the position of the
812 * keys, programmatically creates key names, or any
813 * other reason.
814 * * **"no-auth"**: This command can be run by an un-authenticated client.
815 * Normally this is used by a command that is used
816 * to authenticate a client.
817 */
RM_CreateCommand(RedisModuleCtx * ctx,const char * name,RedisModuleCmdFunc cmdfunc,const char * strflags,int firstkey,int lastkey,int keystep)818 int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) {
819 int64_t flags = strflags ? commandFlagsFromString((char*)strflags) : 0;
820 if (flags == -1) return REDISMODULE_ERR;
821 if ((flags & CMD_MODULE_NO_CLUSTER) && server.cluster_enabled)
822 return REDISMODULE_ERR;
823
824 struct redisCommand *rediscmd;
825 RedisModuleCommandProxy *cp;
826 sds cmdname = sdsnew(name);
827
828 /* Check if the command name is busy. */
829 if (lookupCommand(cmdname) != NULL) {
830 sdsfree(cmdname);
831 return REDISMODULE_ERR;
832 }
833
834 /* Create a command "proxy", which is a structure that is referenced
835 * in the command table, so that the generic command that works as
836 * binding between modules and Redis, can know what function to call
837 * and what the module is.
838 *
839 * Note that we use the Redis command table 'getkeys_proc' in order to
840 * pass a reference to the command proxy structure. */
841 cp = zmalloc(sizeof(*cp));
842 cp->module = ctx->module;
843 cp->func = cmdfunc;
844 cp->rediscmd = zmalloc(sizeof(*rediscmd));
845 cp->rediscmd->name = cmdname;
846 cp->rediscmd->proc = RedisModuleCommandDispatcher;
847 cp->rediscmd->arity = -1;
848 cp->rediscmd->flags = flags | CMD_MODULE;
849 cp->rediscmd->getkeys_proc = (redisGetKeysProc*)(unsigned long)cp;
850 cp->rediscmd->firstkey = firstkey;
851 cp->rediscmd->lastkey = lastkey;
852 cp->rediscmd->keystep = keystep;
853 cp->rediscmd->microseconds = 0;
854 cp->rediscmd->calls = 0;
855 dictAdd(server.commands,sdsdup(cmdname),cp->rediscmd);
856 dictAdd(server.orig_commands,sdsdup(cmdname),cp->rediscmd);
857 cp->rediscmd->id = ACLGetCommandID(cmdname); /* ID used for ACL. */
858 return REDISMODULE_OK;
859 }
860
861 /* Called by RM_Init() to setup the `ctx->module` structure.
862 *
863 * This is an internal function, Redis modules developers don't need
864 * to use it. */
RM_SetModuleAttribs(RedisModuleCtx * ctx,const char * name,int ver,int apiver)865 void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int apiver) {
866 RedisModule *module;
867
868 if (ctx->module != NULL) return;
869 module = zmalloc(sizeof(*module));
870 module->name = sdsnew((char*)name);
871 module->ver = ver;
872 module->apiver = apiver;
873 module->types = listCreate();
874 module->usedby = listCreate();
875 module->using = listCreate();
876 module->filters = listCreate();
877 module->in_call = 0;
878 module->in_hook = 0;
879 module->options = 0;
880 module->info_cb = 0;
881 ctx->module = module;
882 }
883
884 /* Return non-zero if the module name is busy.
885 * Otherwise zero is returned. */
RM_IsModuleNameBusy(const char * name)886 int RM_IsModuleNameBusy(const char *name) {
887 sds modulename = sdsnew(name);
888 dictEntry *de = dictFind(modules,modulename);
889 sdsfree(modulename);
890 return de != NULL;
891 }
892
893 /* Return the current UNIX time in milliseconds. */
RM_Milliseconds(void)894 long long RM_Milliseconds(void) {
895 return mstime();
896 }
897
898 /* Set flags defining capabilities or behavior bit flags.
899 *
900 * REDISMODULE_OPTIONS_HANDLE_IO_ERRORS:
901 * Generally, modules don't need to bother with this, as the process will just
902 * terminate if a read error happens, however, setting this flag would allow
903 * repl-diskless-load to work if enabled.
904 * The module should use RedisModule_IsIOError after reads, before using the
905 * data that was read, and in case of error, propagate it upwards, and also be
906 * able to release the partially populated value and all it's allocations. */
RM_SetModuleOptions(RedisModuleCtx * ctx,int options)907 void RM_SetModuleOptions(RedisModuleCtx *ctx, int options) {
908 ctx->module->options = options;
909 }
910
911 /* Signals that the key is modified from user's perspective (i.e. invalidate WATCH
912 * and client side caching). */
RM_SignalModifiedKey(RedisModuleCtx * ctx,RedisModuleString * keyname)913 int RM_SignalModifiedKey(RedisModuleCtx *ctx, RedisModuleString *keyname) {
914 signalModifiedKey(ctx->client,ctx->client->db,keyname);
915 return REDISMODULE_OK;
916 }
917
918 /* --------------------------------------------------------------------------
919 * Automatic memory management for modules
920 * -------------------------------------------------------------------------- */
921
922 /* Enable automatic memory management.
923 *
924 * The function must be called as the first function of a command implementation
925 * that wants to use automatic memory.
926 *
927 * When enabled, automatic memory management tracks and automatically frees
928 * keys, call replies and Redis string objects once the command returns. In most
929 * cases this eliminates the need of calling the following functions:
930 *
931 * 1) RedisModule_CloseKey()
932 * 2) RedisModule_FreeCallReply()
933 * 3) RedisModule_FreeString()
934 *
935 * These functions can still be used with automatic memory management enabled,
936 * to optimize loops that make numerous allocations for example. */
RM_AutoMemory(RedisModuleCtx * ctx)937 void RM_AutoMemory(RedisModuleCtx *ctx) {
938 ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY;
939 }
940
941 /* Add a new object to release automatically when the callback returns. */
autoMemoryAdd(RedisModuleCtx * ctx,int type,void * ptr)942 void autoMemoryAdd(RedisModuleCtx *ctx, int type, void *ptr) {
943 if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
944 if (ctx->amqueue_used == ctx->amqueue_len) {
945 ctx->amqueue_len *= 2;
946 if (ctx->amqueue_len < 16) ctx->amqueue_len = 16;
947 ctx->amqueue = zrealloc(ctx->amqueue,sizeof(struct AutoMemEntry)*ctx->amqueue_len);
948 }
949 ctx->amqueue[ctx->amqueue_used].type = type;
950 ctx->amqueue[ctx->amqueue_used].ptr = ptr;
951 ctx->amqueue_used++;
952 }
953
954 /* Mark an object as freed in the auto release queue, so that users can still
955 * free things manually if they want.
956 *
957 * The function returns 1 if the object was actually found in the auto memory
958 * pool, otherwise 0 is returned. */
autoMemoryFreed(RedisModuleCtx * ctx,int type,void * ptr)959 int autoMemoryFreed(RedisModuleCtx *ctx, int type, void *ptr) {
960 if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return 0;
961
962 int count = (ctx->amqueue_used+1)/2;
963 for (int j = 0; j < count; j++) {
964 for (int side = 0; side < 2; side++) {
965 /* For side = 0 check right side of the array, for
966 * side = 1 check the left side instead (zig-zag scanning). */
967 int i = (side == 0) ? (ctx->amqueue_used - 1 - j) : j;
968 if (ctx->amqueue[i].type == type &&
969 ctx->amqueue[i].ptr == ptr)
970 {
971 ctx->amqueue[i].type = REDISMODULE_AM_FREED;
972
973 /* Switch the freed element and the last element, to avoid growing
974 * the queue unnecessarily if we allocate/free in a loop */
975 if (i != ctx->amqueue_used-1) {
976 ctx->amqueue[i] = ctx->amqueue[ctx->amqueue_used-1];
977 }
978
979 /* Reduce the size of the queue because we either moved the top
980 * element elsewhere or freed it */
981 ctx->amqueue_used--;
982 return 1;
983 }
984 }
985 }
986 return 0;
987 }
988
989 /* Release all the objects in queue. */
autoMemoryCollect(RedisModuleCtx * ctx)990 void autoMemoryCollect(RedisModuleCtx *ctx) {
991 if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
992 /* Clear the AUTO_MEMORY flag from the context, otherwise the functions
993 * we call to free the resources, will try to scan the auto release
994 * queue to mark the entries as freed. */
995 ctx->flags &= ~REDISMODULE_CTX_AUTO_MEMORY;
996 int j;
997 for (j = 0; j < ctx->amqueue_used; j++) {
998 void *ptr = ctx->amqueue[j].ptr;
999 switch(ctx->amqueue[j].type) {
1000 case REDISMODULE_AM_STRING: decrRefCount(ptr); break;
1001 case REDISMODULE_AM_REPLY: RM_FreeCallReply(ptr); break;
1002 case REDISMODULE_AM_KEY: RM_CloseKey(ptr); break;
1003 case REDISMODULE_AM_DICT: RM_FreeDict(NULL,ptr); break;
1004 case REDISMODULE_AM_INFO: RM_FreeServerInfo(NULL,ptr); break;
1005 }
1006 }
1007 ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY;
1008 zfree(ctx->amqueue);
1009 ctx->amqueue = NULL;
1010 ctx->amqueue_len = 0;
1011 ctx->amqueue_used = 0;
1012 }
1013
1014 /* --------------------------------------------------------------------------
1015 * String objects APIs
1016 * -------------------------------------------------------------------------- */
1017
1018 /* Create a new module string object. The returned string must be freed
1019 * with RedisModule_FreeString(), unless automatic memory is enabled.
1020 *
1021 * The string is created by copying the `len` bytes starting
1022 * at `ptr`. No reference is retained to the passed buffer.
1023 *
1024 * The module context 'ctx' is optional and may be NULL if you want to create
1025 * a string out of the context scope. However in that case, the automatic
1026 * memory management will not be available, and the string memory must be
1027 * managed manually. */
RM_CreateString(RedisModuleCtx * ctx,const char * ptr,size_t len)1028 RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len) {
1029 RedisModuleString *o = createStringObject(ptr,len);
1030 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
1031 return o;
1032 }
1033
1034 /* Create a new module string object from a printf format and arguments.
1035 * The returned string must be freed with RedisModule_FreeString(), unless
1036 * automatic memory is enabled.
1037 *
1038 * The string is created using the sds formatter function sdscatvprintf().
1039 *
1040 * The passed context 'ctx' may be NULL if necessary, see the
1041 * RedisModule_CreateString() documentation for more info. */
RM_CreateStringPrintf(RedisModuleCtx * ctx,const char * fmt,...)1042 RedisModuleString *RM_CreateStringPrintf(RedisModuleCtx *ctx, const char *fmt, ...) {
1043 sds s = sdsempty();
1044
1045 va_list ap;
1046 va_start(ap, fmt);
1047 s = sdscatvprintf(s, fmt, ap);
1048 va_end(ap);
1049
1050 RedisModuleString *o = createObject(OBJ_STRING, s);
1051 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
1052
1053 return o;
1054 }
1055
1056
1057 /* Like RedisModule_CreatString(), but creates a string starting from a long long
1058 * integer instead of taking a buffer and its length.
1059 *
1060 * The returned string must be released with RedisModule_FreeString() or by
1061 * enabling automatic memory management.
1062 *
1063 * The passed context 'ctx' may be NULL if necessary, see the
1064 * RedisModule_CreateString() documentation for more info. */
RM_CreateStringFromLongLong(RedisModuleCtx * ctx,long long ll)1065 RedisModuleString *RM_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll) {
1066 char buf[LONG_STR_SIZE];
1067 size_t len = ll2string(buf,sizeof(buf),ll);
1068 return RM_CreateString(ctx,buf,len);
1069 }
1070
1071 /* Like RedisModule_CreatString(), but creates a string starting from a double
1072 * instead of taking a buffer and its length.
1073 *
1074 * The returned string must be released with RedisModule_FreeString() or by
1075 * enabling automatic memory management. */
RM_CreateStringFromDouble(RedisModuleCtx * ctx,double d)1076 RedisModuleString *RM_CreateStringFromDouble(RedisModuleCtx *ctx, double d) {
1077 char buf[128];
1078 size_t len = d2string(buf,sizeof(buf),d);
1079 return RM_CreateString(ctx,buf,len);
1080 }
1081
1082 /* Like RedisModule_CreatString(), but creates a string starting from a long
1083 * double.
1084 *
1085 * The returned string must be released with RedisModule_FreeString() or by
1086 * enabling automatic memory management.
1087 *
1088 * The passed context 'ctx' may be NULL if necessary, see the
1089 * RedisModule_CreateString() documentation for more info. */
RM_CreateStringFromLongDouble(RedisModuleCtx * ctx,long double ld,int humanfriendly)1090 RedisModuleString *RM_CreateStringFromLongDouble(RedisModuleCtx *ctx, long double ld, int humanfriendly) {
1091 char buf[MAX_LONG_DOUBLE_CHARS];
1092 size_t len = ld2string(buf,sizeof(buf),ld,
1093 (humanfriendly ? LD_STR_HUMAN : LD_STR_AUTO));
1094 return RM_CreateString(ctx,buf,len);
1095 }
1096
1097 /* Like RedisModule_CreatString(), but creates a string starting from another
1098 * RedisModuleString.
1099 *
1100 * The returned string must be released with RedisModule_FreeString() or by
1101 * enabling automatic memory management.
1102 *
1103 * The passed context 'ctx' may be NULL if necessary, see the
1104 * RedisModule_CreateString() documentation for more info. */
RM_CreateStringFromString(RedisModuleCtx * ctx,const RedisModuleString * str)1105 RedisModuleString *RM_CreateStringFromString(RedisModuleCtx *ctx, const RedisModuleString *str) {
1106 RedisModuleString *o = dupStringObject(str);
1107 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
1108 return o;
1109 }
1110
1111 /* Free a module string object obtained with one of the Redis modules API calls
1112 * that return new string objects.
1113 *
1114 * It is possible to call this function even when automatic memory management
1115 * is enabled. In that case the string will be released ASAP and removed
1116 * from the pool of string to release at the end.
1117 *
1118 * If the string was created with a NULL context 'ctx', it is also possible to
1119 * pass ctx as NULL when releasing the string (but passing a context will not
1120 * create any issue). Strings created with a context should be freed also passing
1121 * the context, so if you want to free a string out of context later, make sure
1122 * to create it using a NULL context. */
RM_FreeString(RedisModuleCtx * ctx,RedisModuleString * str)1123 void RM_FreeString(RedisModuleCtx *ctx, RedisModuleString *str) {
1124 decrRefCount(str);
1125 if (ctx != NULL) autoMemoryFreed(ctx,REDISMODULE_AM_STRING,str);
1126 }
1127
1128 /* Every call to this function, will make the string 'str' requiring
1129 * an additional call to RedisModule_FreeString() in order to really
1130 * free the string. Note that the automatic freeing of the string obtained
1131 * enabling modules automatic memory management counts for one
1132 * RedisModule_FreeString() call (it is just executed automatically).
1133 *
1134 * Normally you want to call this function when, at the same time
1135 * the following conditions are true:
1136 *
1137 * 1) You have automatic memory management enabled.
1138 * 2) You want to create string objects.
1139 * 3) Those string objects you create need to live *after* the callback
1140 * function(for example a command implementation) creating them returns.
1141 *
1142 * Usually you want this in order to store the created string object
1143 * into your own data structure, for example when implementing a new data
1144 * type.
1145 *
1146 * Note that when memory management is turned off, you don't need
1147 * any call to RetainString() since creating a string will always result
1148 * into a string that lives after the callback function returns, if
1149 * no FreeString() call is performed.
1150 *
1151 * It is possible to call this function with a NULL context. */
RM_RetainString(RedisModuleCtx * ctx,RedisModuleString * str)1152 void RM_RetainString(RedisModuleCtx *ctx, RedisModuleString *str) {
1153 if (ctx == NULL || !autoMemoryFreed(ctx,REDISMODULE_AM_STRING,str)) {
1154 /* Increment the string reference counting only if we can't
1155 * just remove the object from the list of objects that should
1156 * be reclaimed. Why we do that, instead of just incrementing
1157 * the refcount in any case, and let the automatic FreeString()
1158 * call at the end to bring the refcount back at the desired
1159 * value? Because this way we ensure that the object refcount
1160 * value is 1 (instead of going to 2 to be dropped later to 1)
1161 * after the call to this function. This is needed for functions
1162 * like RedisModule_StringAppendBuffer() to work. */
1163 incrRefCount(str);
1164 }
1165 }
1166
1167 /**
1168 * This function can be used instead of RedisModule_RetainString().
1169 * The main difference between the two is that this function will always
1170 * succeed, whereas RedisModule_RetainString() may fail because of an
1171 * assertion.
1172 *
1173 * The function returns a pointer to RedisModuleString, which is owned
1174 * by the caller. It requires a call to RedisModule_FreeString() to free
1175 * the string when automatic memory management is disabled for the context.
1176 * When automatic memory management is enabled, you can either call
1177 * RedisModule_FreeString() or let the automation free it.
1178 *
1179 * This function is more efficient than RedisModule_CreateStringFromString()
1180 * because whenever possible, it avoids copying the underlying
1181 * RedisModuleString. The disadvantage of using this function is that it
1182 * might not be possible to use RedisModule_StringAppendBuffer() on the
1183 * returned RedisModuleString.
1184 *
1185 * It is possible to call this function with a NULL context.
1186 */
RM_HoldString(RedisModuleCtx * ctx,RedisModuleString * str)1187 RedisModuleString* RM_HoldString(RedisModuleCtx *ctx, RedisModuleString *str) {
1188 if (str->refcount == OBJ_STATIC_REFCOUNT) {
1189 return RM_CreateStringFromString(ctx, str);
1190 }
1191
1192 incrRefCount(str);
1193 if (ctx != NULL) {
1194 /*
1195 * Put the str in the auto memory management of the ctx.
1196 * It might already be there, in this case, the ref count will
1197 * be 2 and we will decrease the ref count twice and free the
1198 * object in the auto memory free function.
1199 *
1200 * Why we can not do the same trick of just remove the object
1201 * from the auto memory (like in RM_RetainString)?
1202 * This code shows the issue:
1203 *
1204 * RM_AutoMemory(ctx);
1205 * str1 = RM_CreateString(ctx, "test", 4);
1206 * str2 = RM_HoldString(ctx, str1);
1207 * RM_FreeString(str1);
1208 * RM_FreeString(str2);
1209 *
1210 * If after the RM_HoldString we would just remove the string from
1211 * the auto memory, this example will cause access to a freed memory
1212 * on 'RM_FreeString(str2);' because the String will be free
1213 * on 'RM_FreeString(str1);'.
1214 *
1215 * So it's safer to just increase the ref count
1216 * and add the String to auto memory again.
1217 *
1218 * The limitation is that it is not possible to use RedisModule_StringAppendBuffer
1219 * on the String.
1220 */
1221 autoMemoryAdd(ctx,REDISMODULE_AM_STRING,str);
1222 }
1223 return str;
1224 }
1225
1226 /* Given a string module object, this function returns the string pointer
1227 * and length of the string. The returned pointer and length should only
1228 * be used for read only accesses and never modified. */
RM_StringPtrLen(const RedisModuleString * str,size_t * len)1229 const char *RM_StringPtrLen(const RedisModuleString *str, size_t *len) {
1230 if (str == NULL) {
1231 const char *errmsg = "(NULL string reply referenced in module)";
1232 if (len) *len = strlen(errmsg);
1233 return errmsg;
1234 }
1235 if (len) *len = sdslen(str->ptr);
1236 return str->ptr;
1237 }
1238
1239 /* --------------------------------------------------------------------------
1240 * Higher level string operations
1241 * ------------------------------------------------------------------------- */
1242
1243 /* Convert the string into a long long integer, storing it at `*ll`.
1244 * Returns REDISMODULE_OK on success. If the string can't be parsed
1245 * as a valid, strict long long (no spaces before/after), REDISMODULE_ERR
1246 * is returned. */
RM_StringToLongLong(const RedisModuleString * str,long long * ll)1247 int RM_StringToLongLong(const RedisModuleString *str, long long *ll) {
1248 return string2ll(str->ptr,sdslen(str->ptr),ll) ? REDISMODULE_OK :
1249 REDISMODULE_ERR;
1250 }
1251
1252 /* Convert the string into a double, storing it at `*d`.
1253 * Returns REDISMODULE_OK on success or REDISMODULE_ERR if the string is
1254 * not a valid string representation of a double value. */
RM_StringToDouble(const RedisModuleString * str,double * d)1255 int RM_StringToDouble(const RedisModuleString *str, double *d) {
1256 int retval = getDoubleFromObject(str,d);
1257 return (retval == C_OK) ? REDISMODULE_OK : REDISMODULE_ERR;
1258 }
1259
1260 /* Convert the string into a long double, storing it at `*ld`.
1261 * Returns REDISMODULE_OK on success or REDISMODULE_ERR if the string is
1262 * not a valid string representation of a double value. */
RM_StringToLongDouble(const RedisModuleString * str,long double * ld)1263 int RM_StringToLongDouble(const RedisModuleString *str, long double *ld) {
1264 int retval = string2ld(str->ptr,sdslen(str->ptr),ld);
1265 return retval ? REDISMODULE_OK : REDISMODULE_ERR;
1266 }
1267
1268 /* Compare two string objects, returning -1, 0 or 1 respectively if
1269 * a < b, a == b, a > b. Strings are compared byte by byte as two
1270 * binary blobs without any encoding care / collation attempt. */
RM_StringCompare(RedisModuleString * a,RedisModuleString * b)1271 int RM_StringCompare(RedisModuleString *a, RedisModuleString *b) {
1272 return compareStringObjects(a,b);
1273 }
1274
1275 /* Return the (possibly modified in encoding) input 'str' object if
1276 * the string is unshared, otherwise NULL is returned. */
moduleAssertUnsharedString(RedisModuleString * str)1277 RedisModuleString *moduleAssertUnsharedString(RedisModuleString *str) {
1278 if (str->refcount != 1) {
1279 serverLog(LL_WARNING,
1280 "Module attempted to use an in-place string modify operation "
1281 "with a string referenced multiple times. Please check the code "
1282 "for API usage correctness.");
1283 return NULL;
1284 }
1285 if (str->encoding == OBJ_ENCODING_EMBSTR) {
1286 /* Note: here we "leak" the additional allocation that was
1287 * used in order to store the embedded string in the object. */
1288 str->ptr = sdsnewlen(str->ptr,sdslen(str->ptr));
1289 str->encoding = OBJ_ENCODING_RAW;
1290 } else if (str->encoding == OBJ_ENCODING_INT) {
1291 /* Convert the string from integer to raw encoding. */
1292 str->ptr = sdsfromlonglong((long)str->ptr);
1293 str->encoding = OBJ_ENCODING_RAW;
1294 }
1295 return str;
1296 }
1297
1298 /* Append the specified buffer to the string 'str'. The string must be a
1299 * string created by the user that is referenced only a single time, otherwise
1300 * REDISMODULE_ERR is returned and the operation is not performed. */
RM_StringAppendBuffer(RedisModuleCtx * ctx,RedisModuleString * str,const char * buf,size_t len)1301 int RM_StringAppendBuffer(RedisModuleCtx *ctx, RedisModuleString *str, const char *buf, size_t len) {
1302 UNUSED(ctx);
1303 str = moduleAssertUnsharedString(str);
1304 if (str == NULL) return REDISMODULE_ERR;
1305 str->ptr = sdscatlen(str->ptr,buf,len);
1306 return REDISMODULE_OK;
1307 }
1308
1309 /* --------------------------------------------------------------------------
1310 * Reply APIs
1311 *
1312 * Most functions always return REDISMODULE_OK so you can use it with
1313 * 'return' in order to return from the command implementation with:
1314 *
1315 * if (... some condition ...)
1316 * return RM_ReplyWithLongLong(ctx,mycount);
1317 * -------------------------------------------------------------------------- */
1318
1319 /* Send an error about the number of arguments given to the command,
1320 * citing the command name in the error message.
1321 *
1322 * Example:
1323 *
1324 * if (argc != 3) return RedisModule_WrongArity(ctx);
1325 */
RM_WrongArity(RedisModuleCtx * ctx)1326 int RM_WrongArity(RedisModuleCtx *ctx) {
1327 addReplyErrorFormat(ctx->client,
1328 "wrong number of arguments for '%s' command",
1329 (char*)ctx->client->argv[0]->ptr);
1330 return REDISMODULE_OK;
1331 }
1332
1333 /* Return the client object the `RM_Reply*` functions should target.
1334 * Normally this is just `ctx->client`, that is the client that called
1335 * the module command, however in the case of thread safe contexts there
1336 * is no directly associated client (since it would not be safe to access
1337 * the client from a thread), so instead the blocked client object referenced
1338 * in the thread safe context, has a fake client that we just use to accumulate
1339 * the replies. Later, when the client is unblocked, the accumulated replies
1340 * are appended to the actual client.
1341 *
1342 * The function returns the client pointer depending on the context, or
1343 * NULL if there is no potential client. This happens when we are in the
1344 * context of a thread safe context that was not initialized with a blocked
1345 * client object. Other contexts without associated clients are the ones
1346 * initialized to run the timers callbacks. */
moduleGetReplyClient(RedisModuleCtx * ctx)1347 client *moduleGetReplyClient(RedisModuleCtx *ctx) {
1348 if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) {
1349 if (ctx->blocked_client)
1350 return ctx->blocked_client->reply_client;
1351 else
1352 return NULL;
1353 } else {
1354 /* If this is a non thread safe context, just return the client
1355 * that is running the command if any. This may be NULL as well
1356 * in the case of contexts that are not executed with associated
1357 * clients, like timer contexts. */
1358 return ctx->client;
1359 }
1360 }
1361
1362 /* Send an integer reply to the client, with the specified long long value.
1363 * The function always returns REDISMODULE_OK. */
RM_ReplyWithLongLong(RedisModuleCtx * ctx,long long ll)1364 int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll) {
1365 client *c = moduleGetReplyClient(ctx);
1366 if (c == NULL) return REDISMODULE_OK;
1367 addReplyLongLong(c,ll);
1368 return REDISMODULE_OK;
1369 }
1370
1371 /* Reply with an error or simple string (status message). Used to implement
1372 * ReplyWithSimpleString() and ReplyWithError().
1373 * The function always returns REDISMODULE_OK. */
replyWithStatus(RedisModuleCtx * ctx,const char * msg,char * prefix)1374 int replyWithStatus(RedisModuleCtx *ctx, const char *msg, char *prefix) {
1375 client *c = moduleGetReplyClient(ctx);
1376 if (c == NULL) return REDISMODULE_OK;
1377 addReplyProto(c,prefix,strlen(prefix));
1378 addReplyProto(c,msg,strlen(msg));
1379 addReplyProto(c,"\r\n",2);
1380 return REDISMODULE_OK;
1381 }
1382
1383 /* Reply with the error 'err'.
1384 *
1385 * Note that 'err' must contain all the error, including
1386 * the initial error code. The function only provides the initial "-", so
1387 * the usage is, for example:
1388 *
1389 * RedisModule_ReplyWithError(ctx,"ERR Wrong Type");
1390 *
1391 * and not just:
1392 *
1393 * RedisModule_ReplyWithError(ctx,"Wrong Type");
1394 *
1395 * The function always returns REDISMODULE_OK.
1396 */
RM_ReplyWithError(RedisModuleCtx * ctx,const char * err)1397 int RM_ReplyWithError(RedisModuleCtx *ctx, const char *err) {
1398 return replyWithStatus(ctx,err,"-");
1399 }
1400
1401 /* Reply with a simple string (+... \r\n in RESP protocol). This replies
1402 * are suitable only when sending a small non-binary string with small
1403 * overhead, like "OK" or similar replies.
1404 *
1405 * The function always returns REDISMODULE_OK. */
RM_ReplyWithSimpleString(RedisModuleCtx * ctx,const char * msg)1406 int RM_ReplyWithSimpleString(RedisModuleCtx *ctx, const char *msg) {
1407 return replyWithStatus(ctx,msg,"+");
1408 }
1409
1410 /* Reply with an array type of 'len' elements. However 'len' other calls
1411 * to `ReplyWith*` style functions must follow in order to emit the elements
1412 * of the array.
1413 *
1414 * When producing arrays with a number of element that is not known beforehand
1415 * the function can be called with the special count
1416 * REDISMODULE_POSTPONED_ARRAY_LEN, and the actual number of elements can be
1417 * later set with RedisModule_ReplySetArrayLength() (which will set the
1418 * latest "open" count if there are multiple ones).
1419 *
1420 * The function always returns REDISMODULE_OK. */
RM_ReplyWithArray(RedisModuleCtx * ctx,long len)1421 int RM_ReplyWithArray(RedisModuleCtx *ctx, long len) {
1422 client *c = moduleGetReplyClient(ctx);
1423 if (c == NULL) return REDISMODULE_OK;
1424 if (len == REDISMODULE_POSTPONED_ARRAY_LEN) {
1425 ctx->postponed_arrays = zrealloc(ctx->postponed_arrays,sizeof(void*)*
1426 (ctx->postponed_arrays_count+1));
1427 ctx->postponed_arrays[ctx->postponed_arrays_count] =
1428 addReplyDeferredLen(c);
1429 ctx->postponed_arrays_count++;
1430 } else {
1431 addReplyArrayLen(c,len);
1432 }
1433 return REDISMODULE_OK;
1434 }
1435
1436 /* Reply to the client with a null array, simply null in RESP3
1437 * null array in RESP2.
1438 *
1439 * The function always returns REDISMODULE_OK. */
RM_ReplyWithNullArray(RedisModuleCtx * ctx)1440 int RM_ReplyWithNullArray(RedisModuleCtx *ctx) {
1441 client *c = moduleGetReplyClient(ctx);
1442 if (c == NULL) return REDISMODULE_OK;
1443 addReplyNullArray(c);
1444 return REDISMODULE_OK;
1445 }
1446
1447 /* Reply to the client with an empty array.
1448 *
1449 * The function always returns REDISMODULE_OK. */
RM_ReplyWithEmptyArray(RedisModuleCtx * ctx)1450 int RM_ReplyWithEmptyArray(RedisModuleCtx *ctx) {
1451 client *c = moduleGetReplyClient(ctx);
1452 if (c == NULL) return REDISMODULE_OK;
1453 addReply(c,shared.emptyarray);
1454 return REDISMODULE_OK;
1455 }
1456
1457 /* When RedisModule_ReplyWithArray() is used with the argument
1458 * REDISMODULE_POSTPONED_ARRAY_LEN, because we don't know beforehand the number
1459 * of items we are going to output as elements of the array, this function
1460 * will take care to set the array length.
1461 *
1462 * Since it is possible to have multiple array replies pending with unknown
1463 * length, this function guarantees to always set the latest array length
1464 * that was created in a postponed way.
1465 *
1466 * For example in order to output an array like [1,[10,20,30]] we
1467 * could write:
1468 *
1469 * RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_ARRAY_LEN);
1470 * RedisModule_ReplyWithLongLong(ctx,1);
1471 * RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_ARRAY_LEN);
1472 * RedisModule_ReplyWithLongLong(ctx,10);
1473 * RedisModule_ReplyWithLongLong(ctx,20);
1474 * RedisModule_ReplyWithLongLong(ctx,30);
1475 * RedisModule_ReplySetArrayLength(ctx,3); // Set len of 10,20,30 array.
1476 * RedisModule_ReplySetArrayLength(ctx,2); // Set len of top array
1477 *
1478 * Note that in the above example there is no reason to postpone the array
1479 * length, since we produce a fixed number of elements, but in the practice
1480 * the code may use an iterator or other ways of creating the output so
1481 * that is not easy to calculate in advance the number of elements.
1482 */
RM_ReplySetArrayLength(RedisModuleCtx * ctx,long len)1483 void RM_ReplySetArrayLength(RedisModuleCtx *ctx, long len) {
1484 client *c = moduleGetReplyClient(ctx);
1485 if (c == NULL) return;
1486 if (ctx->postponed_arrays_count == 0) {
1487 serverLog(LL_WARNING,
1488 "API misuse detected in module %s: "
1489 "RedisModule_ReplySetArrayLength() called without previous "
1490 "RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_ARRAY_LEN) "
1491 "call.", ctx->module->name);
1492 return;
1493 }
1494 ctx->postponed_arrays_count--;
1495 setDeferredArrayLen(c,
1496 ctx->postponed_arrays[ctx->postponed_arrays_count],
1497 len);
1498 if (ctx->postponed_arrays_count == 0) {
1499 zfree(ctx->postponed_arrays);
1500 ctx->postponed_arrays = NULL;
1501 }
1502 }
1503
1504 /* Reply with a bulk string, taking in input a C buffer pointer and length.
1505 *
1506 * The function always returns REDISMODULE_OK. */
RM_ReplyWithStringBuffer(RedisModuleCtx * ctx,const char * buf,size_t len)1507 int RM_ReplyWithStringBuffer(RedisModuleCtx *ctx, const char *buf, size_t len) {
1508 client *c = moduleGetReplyClient(ctx);
1509 if (c == NULL) return REDISMODULE_OK;
1510 addReplyBulkCBuffer(c,(char*)buf,len);
1511 return REDISMODULE_OK;
1512 }
1513
1514 /* Reply with a bulk string, taking in input a C buffer pointer that is
1515 * assumed to be null-terminated.
1516 *
1517 * The function always returns REDISMODULE_OK. */
RM_ReplyWithCString(RedisModuleCtx * ctx,const char * buf)1518 int RM_ReplyWithCString(RedisModuleCtx *ctx, const char *buf) {
1519 client *c = moduleGetReplyClient(ctx);
1520 if (c == NULL) return REDISMODULE_OK;
1521 addReplyBulkCString(c,(char*)buf);
1522 return REDISMODULE_OK;
1523 }
1524
1525 /* Reply with a bulk string, taking in input a RedisModuleString object.
1526 *
1527 * The function always returns REDISMODULE_OK. */
RM_ReplyWithString(RedisModuleCtx * ctx,RedisModuleString * str)1528 int RM_ReplyWithString(RedisModuleCtx *ctx, RedisModuleString *str) {
1529 client *c = moduleGetReplyClient(ctx);
1530 if (c == NULL) return REDISMODULE_OK;
1531 addReplyBulk(c,str);
1532 return REDISMODULE_OK;
1533 }
1534
1535 /* Reply with an empty string.
1536 *
1537 * The function always returns REDISMODULE_OK. */
RM_ReplyWithEmptyString(RedisModuleCtx * ctx)1538 int RM_ReplyWithEmptyString(RedisModuleCtx *ctx) {
1539 client *c = moduleGetReplyClient(ctx);
1540 if (c == NULL) return REDISMODULE_OK;
1541 addReply(c,shared.emptybulk);
1542 return REDISMODULE_OK;
1543 }
1544
1545 /* Reply with a binary safe string, which should not be escaped or filtered
1546 * taking in input a C buffer pointer and length.
1547 *
1548 * The function always returns REDISMODULE_OK. */
RM_ReplyWithVerbatimString(RedisModuleCtx * ctx,const char * buf,size_t len)1549 int RM_ReplyWithVerbatimString(RedisModuleCtx *ctx, const char *buf, size_t len) {
1550 client *c = moduleGetReplyClient(ctx);
1551 if (c == NULL) return REDISMODULE_OK;
1552 addReplyVerbatim(c, buf, len, "txt");
1553 return REDISMODULE_OK;
1554 }
1555
1556 /* Reply to the client with a NULL.
1557 *
1558 * The function always returns REDISMODULE_OK. */
RM_ReplyWithNull(RedisModuleCtx * ctx)1559 int RM_ReplyWithNull(RedisModuleCtx *ctx) {
1560 client *c = moduleGetReplyClient(ctx);
1561 if (c == NULL) return REDISMODULE_OK;
1562 addReplyNull(c);
1563 return REDISMODULE_OK;
1564 }
1565
1566 /* Reply exactly what a Redis command returned us with RedisModule_Call().
1567 * This function is useful when we use RedisModule_Call() in order to
1568 * execute some command, as we want to reply to the client exactly the
1569 * same reply we obtained by the command.
1570 *
1571 * The function always returns REDISMODULE_OK. */
RM_ReplyWithCallReply(RedisModuleCtx * ctx,RedisModuleCallReply * reply)1572 int RM_ReplyWithCallReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply) {
1573 client *c = moduleGetReplyClient(ctx);
1574 if (c == NULL) return REDISMODULE_OK;
1575 sds proto = sdsnewlen(reply->proto, reply->protolen);
1576 addReplySds(c,proto);
1577 return REDISMODULE_OK;
1578 }
1579
1580 /* Send a string reply obtained converting the double 'd' into a bulk string.
1581 * This function is basically equivalent to converting a double into
1582 * a string into a C buffer, and then calling the function
1583 * RedisModule_ReplyWithStringBuffer() with the buffer and length.
1584 *
1585 * The function always returns REDISMODULE_OK. */
RM_ReplyWithDouble(RedisModuleCtx * ctx,double d)1586 int RM_ReplyWithDouble(RedisModuleCtx *ctx, double d) {
1587 client *c = moduleGetReplyClient(ctx);
1588 if (c == NULL) return REDISMODULE_OK;
1589 addReplyDouble(c,d);
1590 return REDISMODULE_OK;
1591 }
1592
1593 /* Send a string reply obtained converting the long double 'ld' into a bulk
1594 * string. This function is basically equivalent to converting a long double
1595 * into a string into a C buffer, and then calling the function
1596 * RedisModule_ReplyWithStringBuffer() with the buffer and length.
1597 * The double string uses human readable formatting (see
1598 * `addReplyHumanLongDouble` in networking.c).
1599 *
1600 * The function always returns REDISMODULE_OK. */
RM_ReplyWithLongDouble(RedisModuleCtx * ctx,long double ld)1601 int RM_ReplyWithLongDouble(RedisModuleCtx *ctx, long double ld) {
1602 client *c = moduleGetReplyClient(ctx);
1603 if (c == NULL) return REDISMODULE_OK;
1604 addReplyHumanLongDouble(c, ld);
1605 return REDISMODULE_OK;
1606 }
1607
1608 /* --------------------------------------------------------------------------
1609 * Commands replication API
1610 * -------------------------------------------------------------------------- */
1611
1612 /* Helper function to replicate MULTI the first time we replicate something
1613 * in the context of a command execution. EXEC will be handled by the
1614 * RedisModuleCommandDispatcher() function. */
moduleReplicateMultiIfNeeded(RedisModuleCtx * ctx)1615 void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx) {
1616 /* Skip this if client explicitly wrap the command with MULTI, or if
1617 * the module command was called by a script. */
1618 if (ctx->client->flags & (CLIENT_MULTI|CLIENT_LUA)) return;
1619 /* If we already emitted MULTI return ASAP. */
1620 if (ctx->flags & REDISMODULE_CTX_MULTI_EMITTED) return;
1621 /* If this is a thread safe context, we do not want to wrap commands
1622 * executed into MULTI/EXEC, they are executed as single commands
1623 * from an external client in essence. */
1624 if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) return;
1625 /* If this is a callback context, and not a module command execution
1626 * context, we have to setup the op array for the "also propagate" API
1627 * so that RM_Replicate() will work. */
1628 if (!(ctx->flags & REDISMODULE_CTX_MODULE_COMMAND_CALL)) {
1629 ctx->saved_oparray = server.also_propagate;
1630 redisOpArrayInit(&server.also_propagate);
1631 }
1632 execCommandPropagateMulti(ctx->client);
1633 ctx->flags |= REDISMODULE_CTX_MULTI_EMITTED;
1634 }
1635
1636 /* Replicate the specified command and arguments to slaves and AOF, as effect
1637 * of execution of the calling command implementation.
1638 *
1639 * The replicated commands are always wrapped into the MULTI/EXEC that
1640 * contains all the commands replicated in a given module command
1641 * execution. However the commands replicated with RedisModule_Call()
1642 * are the first items, the ones replicated with RedisModule_Replicate()
1643 * will all follow before the EXEC.
1644 *
1645 * Modules should try to use one interface or the other.
1646 *
1647 * This command follows exactly the same interface of RedisModule_Call(),
1648 * so a set of format specifiers must be passed, followed by arguments
1649 * matching the provided format specifiers.
1650 *
1651 * Please refer to RedisModule_Call() for more information.
1652 *
1653 * Using the special "A" and "R" modifiers, the caller can exclude either
1654 * the AOF or the replicas from the propagation of the specified command.
1655 * Otherwise, by default, the command will be propagated in both channels.
1656 *
1657 * ## Note about calling this function from a thread safe context:
1658 *
1659 * Normally when you call this function from the callback implementing a
1660 * module command, or any other callback provided by the Redis Module API,
1661 * Redis will accumulate all the calls to this function in the context of
1662 * the callback, and will propagate all the commands wrapped in a MULTI/EXEC
1663 * transaction. However when calling this function from a threaded safe context
1664 * that can live an undefined amount of time, and can be locked/unlocked in
1665 * at will, the behavior is different: MULTI/EXEC wrapper is not emitted
1666 * and the command specified is inserted in the AOF and replication stream
1667 * immediately.
1668 *
1669 * ## Return value
1670 *
1671 * The command returns REDISMODULE_ERR if the format specifiers are invalid
1672 * or the command name does not belong to a known command. */
RM_Replicate(RedisModuleCtx * ctx,const char * cmdname,const char * fmt,...)1673 int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
1674 struct redisCommand *cmd;
1675 robj **argv = NULL;
1676 int argc = 0, flags = 0, j;
1677 va_list ap;
1678
1679 cmd = lookupCommandByCString((char*)cmdname);
1680 if (!cmd) return REDISMODULE_ERR;
1681
1682 /* Create the client and dispatch the command. */
1683 va_start(ap, fmt);
1684 argv = moduleCreateArgvFromUserFormat(cmdname,fmt,&argc,&flags,ap);
1685 va_end(ap);
1686 if (argv == NULL) return REDISMODULE_ERR;
1687
1688 /* Select the propagation target. Usually is AOF + replicas, however
1689 * the caller can exclude one or the other using the "A" or "R"
1690 * modifiers. */
1691 int target = 0;
1692 if (!(flags & REDISMODULE_ARGV_NO_AOF)) target |= PROPAGATE_AOF;
1693 if (!(flags & REDISMODULE_ARGV_NO_REPLICAS)) target |= PROPAGATE_REPL;
1694
1695 /* Replicate! When we are in a threaded context, we want to just insert
1696 * the replicated command ASAP, since it is not clear when the context
1697 * will stop being used, so accumulating stuff does not make much sense,
1698 * nor we could easily use the alsoPropagate() API from threads. */
1699 if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) {
1700 propagate(cmd,ctx->client->db->id,argv,argc,target);
1701 } else {
1702 moduleReplicateMultiIfNeeded(ctx);
1703 alsoPropagate(cmd,ctx->client->db->id,argv,argc,target);
1704 }
1705
1706 /* Release the argv. */
1707 for (j = 0; j < argc; j++) decrRefCount(argv[j]);
1708 zfree(argv);
1709 server.dirty++;
1710 return REDISMODULE_OK;
1711 }
1712
1713 /* This function will replicate the command exactly as it was invoked
1714 * by the client. Note that this function will not wrap the command into
1715 * a MULTI/EXEC stanza, so it should not be mixed with other replication
1716 * commands.
1717 *
1718 * Basically this form of replication is useful when you want to propagate
1719 * the command to the slaves and AOF file exactly as it was called, since
1720 * the command can just be re-executed to deterministically re-create the
1721 * new state starting from the old one.
1722 *
1723 * The function always returns REDISMODULE_OK. */
RM_ReplicateVerbatim(RedisModuleCtx * ctx)1724 int RM_ReplicateVerbatim(RedisModuleCtx *ctx) {
1725 alsoPropagate(ctx->client->cmd,ctx->client->db->id,
1726 ctx->client->argv,ctx->client->argc,
1727 PROPAGATE_AOF|PROPAGATE_REPL);
1728 server.dirty++;
1729 return REDISMODULE_OK;
1730 }
1731
1732 /* --------------------------------------------------------------------------
1733 * DB and Key APIs -- Generic API
1734 * -------------------------------------------------------------------------- */
1735
1736 /* Return the ID of the current client calling the currently active module
1737 * command. The returned ID has a few guarantees:
1738 *
1739 * 1. The ID is different for each different client, so if the same client
1740 * executes a module command multiple times, it can be recognized as
1741 * having the same ID, otherwise the ID will be different.
1742 * 2. The ID increases monotonically. Clients connecting to the server later
1743 * are guaranteed to get IDs greater than any past ID previously seen.
1744 *
1745 * Valid IDs are from 1 to 2^64-1. If 0 is returned it means there is no way
1746 * to fetch the ID in the context the function was currently called.
1747 *
1748 * After obtaining the ID, it is possible to check if the command execution
1749 * is actually happening in the context of AOF loading, using this macro:
1750 *
1751 * if (RedisModule_IsAOFClient(RedisModule_GetClientId(ctx)) {
1752 * // Handle it differently.
1753 * }
1754 */
RM_GetClientId(RedisModuleCtx * ctx)1755 unsigned long long RM_GetClientId(RedisModuleCtx *ctx) {
1756 if (ctx->client == NULL) return 0;
1757 return ctx->client->id;
1758 }
1759
1760 /* This is an helper for RM_GetClientInfoById() and other functions: given
1761 * a client, it populates the client info structure with the appropriate
1762 * fields depending on the version provided. If the version is not valid
1763 * then REDISMODULE_ERR is returned. Otherwise the function returns
1764 * REDISMODULE_OK and the structure pointed by 'ci' gets populated. */
1765
modulePopulateClientInfoStructure(void * ci,client * client,int structver)1766 int modulePopulateClientInfoStructure(void *ci, client *client, int structver) {
1767 if (structver != 1) return REDISMODULE_ERR;
1768
1769 RedisModuleClientInfoV1 *ci1 = ci;
1770 memset(ci1,0,sizeof(*ci1));
1771 ci1->version = structver;
1772 if (client->flags & CLIENT_MULTI)
1773 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_MULTI;
1774 if (client->flags & CLIENT_PUBSUB)
1775 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_PUBSUB;
1776 if (client->flags & CLIENT_UNIX_SOCKET)
1777 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET;
1778 if (client->flags & CLIENT_TRACKING)
1779 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_TRACKING;
1780 if (client->flags & CLIENT_BLOCKED)
1781 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_BLOCKED;
1782 if (connGetType(client->conn) == CONN_TYPE_TLS)
1783 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_SSL;
1784
1785 int port;
1786 connPeerToString(client->conn,ci1->addr,sizeof(ci1->addr),&port);
1787 ci1->port = port;
1788 ci1->db = client->db->id;
1789 ci1->id = client->id;
1790 return REDISMODULE_OK;
1791 }
1792
1793 /* This is an helper for moduleFireServerEvent() and other functions:
1794 * It populates the replication info structure with the appropriate
1795 * fields depending on the version provided. If the version is not valid
1796 * then REDISMODULE_ERR is returned. Otherwise the function returns
1797 * REDISMODULE_OK and the structure pointed by 'ri' gets populated. */
modulePopulateReplicationInfoStructure(void * ri,int structver)1798 int modulePopulateReplicationInfoStructure(void *ri, int structver) {
1799 if (structver != 1) return REDISMODULE_ERR;
1800
1801 RedisModuleReplicationInfoV1 *ri1 = ri;
1802 memset(ri1,0,sizeof(*ri1));
1803 ri1->version = structver;
1804 ri1->master = server.masterhost==NULL;
1805 ri1->masterhost = server.masterhost? server.masterhost: "";
1806 ri1->masterport = server.masterport;
1807 ri1->replid1 = server.replid;
1808 ri1->replid2 = server.replid2;
1809 ri1->repl1_offset = server.master_repl_offset;
1810 ri1->repl2_offset = server.second_replid_offset;
1811 return REDISMODULE_OK;
1812 }
1813
1814 /* Return information about the client with the specified ID (that was
1815 * previously obtained via the RedisModule_GetClientId() API). If the
1816 * client exists, REDISMODULE_OK is returned, otherwise REDISMODULE_ERR
1817 * is returned.
1818 *
1819 * When the client exist and the `ci` pointer is not NULL, but points to
1820 * a structure of type RedisModuleClientInfo, previously initialized with
1821 * the correct REDISMODULE_CLIENTINFO_INITIALIZER, the structure is populated
1822 * with the following fields:
1823 *
1824 * uint64_t flags; // REDISMODULE_CLIENTINFO_FLAG_*
1825 * uint64_t id; // Client ID
1826 * char addr[46]; // IPv4 or IPv6 address.
1827 * uint16_t port; // TCP port.
1828 * uint16_t db; // Selected DB.
1829 *
1830 * Note: the client ID is useless in the context of this call, since we
1831 * already know, however the same structure could be used in other
1832 * contexts where we don't know the client ID, yet the same structure
1833 * is returned.
1834 *
1835 * With flags having the following meaning:
1836 *
1837 * REDISMODULE_CLIENTINFO_FLAG_SSL Client using SSL connection.
1838 * REDISMODULE_CLIENTINFO_FLAG_PUBSUB Client in Pub/Sub mode.
1839 * REDISMODULE_CLIENTINFO_FLAG_BLOCKED Client blocked in command.
1840 * REDISMODULE_CLIENTINFO_FLAG_TRACKING Client with keys tracking on.
1841 * REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET Client using unix domain socket.
1842 * REDISMODULE_CLIENTINFO_FLAG_MULTI Client in MULTI state.
1843 *
1844 * However passing NULL is a way to just check if the client exists in case
1845 * we are not interested in any additional information.
1846 *
1847 * This is the correct usage when we want the client info structure
1848 * returned:
1849 *
1850 * RedisModuleClientInfo ci = REDISMODULE_CLIENTINFO_INITIALIZER;
1851 * int retval = RedisModule_GetClientInfoById(&ci,client_id);
1852 * if (retval == REDISMODULE_OK) {
1853 * printf("Address: %s\n", ci.addr);
1854 * }
1855 */
RM_GetClientInfoById(void * ci,uint64_t id)1856 int RM_GetClientInfoById(void *ci, uint64_t id) {
1857 client *client = lookupClientByID(id);
1858 if (client == NULL) return REDISMODULE_ERR;
1859 if (ci == NULL) return REDISMODULE_OK;
1860
1861 /* Fill the info structure if passed. */
1862 uint64_t structver = ((uint64_t*)ci)[0];
1863 return modulePopulateClientInfoStructure(ci,client,structver);
1864 }
1865
1866 /* Publish a message to subscribers (see PUBLISH command). */
RM_PublishMessage(RedisModuleCtx * ctx,RedisModuleString * channel,RedisModuleString * message)1867 int RM_PublishMessage(RedisModuleCtx *ctx, RedisModuleString *channel, RedisModuleString *message) {
1868 UNUSED(ctx);
1869 int receivers = pubsubPublishMessage(channel, message);
1870 if (server.cluster_enabled)
1871 clusterPropagatePublish(channel, message);
1872 return receivers;
1873 }
1874
1875 /* Return the currently selected DB. */
RM_GetSelectedDb(RedisModuleCtx * ctx)1876 int RM_GetSelectedDb(RedisModuleCtx *ctx) {
1877 return ctx->client->db->id;
1878 }
1879
1880
1881 /* Return the current context's flags. The flags provide information on the
1882 * current request context (whether the client is a Lua script or in a MULTI),
1883 * and about the Redis instance in general, i.e replication and persistence.
1884 *
1885 * It is possible to call this function even with a NULL context, however
1886 * in this case the following flags will not be reported:
1887 *
1888 * * LUA, MULTI, REPLICATED, DIRTY (see below for more info).
1889 *
1890 * Available flags and their meaning:
1891 *
1892 * * REDISMODULE_CTX_FLAGS_LUA: The command is running in a Lua script
1893 *
1894 * * REDISMODULE_CTX_FLAGS_MULTI: The command is running inside a transaction
1895 *
1896 * * REDISMODULE_CTX_FLAGS_REPLICATED: The command was sent over the replication
1897 * link by the MASTER
1898 *
1899 * * REDISMODULE_CTX_FLAGS_MASTER: The Redis instance is a master
1900 *
1901 * * REDISMODULE_CTX_FLAGS_SLAVE: The Redis instance is a slave
1902 *
1903 * * REDISMODULE_CTX_FLAGS_READONLY: The Redis instance is read-only
1904 *
1905 * * REDISMODULE_CTX_FLAGS_CLUSTER: The Redis instance is in cluster mode
1906 *
1907 * * REDISMODULE_CTX_FLAGS_AOF: The Redis instance has AOF enabled
1908 *
1909 * * REDISMODULE_CTX_FLAGS_RDB: The instance has RDB enabled
1910 *
1911 * * REDISMODULE_CTX_FLAGS_MAXMEMORY: The instance has Maxmemory set
1912 *
1913 * * REDISMODULE_CTX_FLAGS_EVICT: Maxmemory is set and has an eviction
1914 * policy that may delete keys
1915 *
1916 * * REDISMODULE_CTX_FLAGS_OOM: Redis is out of memory according to the
1917 * maxmemory setting.
1918 *
1919 * * REDISMODULE_CTX_FLAGS_OOM_WARNING: Less than 25% of memory remains before
1920 * reaching the maxmemory level.
1921 *
1922 * * REDISMODULE_CTX_FLAGS_LOADING: Server is loading RDB/AOF
1923 *
1924 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_STALE: No active link with the master.
1925 *
1926 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_CONNECTING: The replica is trying to
1927 * connect with the master.
1928 *
1929 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_TRANSFERRING: Master -> Replica RDB
1930 * transfer is in progress.
1931 *
1932 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE: The replica has an active link
1933 * with its master. This is the
1934 * contrary of STALE state.
1935 *
1936 * * REDISMODULE_CTX_FLAGS_ACTIVE_CHILD: There is currently some background
1937 * process active (RDB, AUX or module).
1938 *
1939 * * REDISMODULE_CTX_FLAGS_MULTI_DIRTY: The next EXEC will fail due to dirty
1940 * CAS (touched keys).
1941 *
1942 * * REDISMODULE_CTX_FLAGS_IS_CHILD: Redis is currently running inside
1943 * background child process.
1944 */
RM_GetContextFlags(RedisModuleCtx * ctx)1945 int RM_GetContextFlags(RedisModuleCtx *ctx) {
1946
1947 int flags = 0;
1948 /* Client specific flags */
1949 if (ctx) {
1950 if (ctx->client) {
1951 if (ctx->client->flags & CLIENT_LUA)
1952 flags |= REDISMODULE_CTX_FLAGS_LUA;
1953 if (ctx->client->flags & CLIENT_MULTI)
1954 flags |= REDISMODULE_CTX_FLAGS_MULTI;
1955 /* Module command received from MASTER, is replicated. */
1956 if (ctx->client->flags & CLIENT_MASTER)
1957 flags |= REDISMODULE_CTX_FLAGS_REPLICATED;
1958 }
1959
1960 /* For DIRTY flags, we need the blocked client if used */
1961 client *c = ctx->blocked_client ? ctx->blocked_client->client : ctx->client;
1962 if (c && (c->flags & (CLIENT_DIRTY_CAS|CLIENT_DIRTY_EXEC))) {
1963 flags |= REDISMODULE_CTX_FLAGS_MULTI_DIRTY;
1964 }
1965 }
1966
1967 if (server.cluster_enabled)
1968 flags |= REDISMODULE_CTX_FLAGS_CLUSTER;
1969
1970 if (server.loading)
1971 flags |= REDISMODULE_CTX_FLAGS_LOADING;
1972
1973 /* Maxmemory and eviction policy */
1974 if (server.maxmemory > 0) {
1975 flags |= REDISMODULE_CTX_FLAGS_MAXMEMORY;
1976
1977 if (server.maxmemory_policy != MAXMEMORY_NO_EVICTION)
1978 flags |= REDISMODULE_CTX_FLAGS_EVICT;
1979 }
1980
1981 /* Persistence flags */
1982 if (server.aof_state != AOF_OFF)
1983 flags |= REDISMODULE_CTX_FLAGS_AOF;
1984 if (server.saveparamslen > 0)
1985 flags |= REDISMODULE_CTX_FLAGS_RDB;
1986
1987 /* Replication flags */
1988 if (server.masterhost == NULL) {
1989 flags |= REDISMODULE_CTX_FLAGS_MASTER;
1990 } else {
1991 flags |= REDISMODULE_CTX_FLAGS_SLAVE;
1992 if (server.repl_slave_ro)
1993 flags |= REDISMODULE_CTX_FLAGS_READONLY;
1994
1995 /* Replica state flags. */
1996 if (server.repl_state == REPL_STATE_CONNECT ||
1997 server.repl_state == REPL_STATE_CONNECTING)
1998 {
1999 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_CONNECTING;
2000 } else if (server.repl_state == REPL_STATE_TRANSFER) {
2001 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_TRANSFERRING;
2002 } else if (server.repl_state == REPL_STATE_CONNECTED) {
2003 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE;
2004 }
2005
2006 if (server.repl_state != REPL_STATE_CONNECTED)
2007 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_STALE;
2008 }
2009
2010 /* OOM flag. */
2011 float level;
2012 int retval = getMaxmemoryState(NULL,NULL,NULL,&level);
2013 if (retval == C_ERR) flags |= REDISMODULE_CTX_FLAGS_OOM;
2014 if (level > 0.75) flags |= REDISMODULE_CTX_FLAGS_OOM_WARNING;
2015
2016 /* Presence of children processes. */
2017 if (hasActiveChildProcess()) flags |= REDISMODULE_CTX_FLAGS_ACTIVE_CHILD;
2018 if (server.in_fork_child) flags |= REDISMODULE_CTX_FLAGS_IS_CHILD;
2019
2020 return flags;
2021 }
2022
2023 /* Returns true if some client sent the CLIENT PAUSE command to the server or
2024 * if Redis Cluster is doing a manual failover, and paused tue clients.
2025 * This is needed when we have a master with replicas, and want to write,
2026 * without adding further data to the replication channel, that the replicas
2027 * replication offset, match the one of the master. When this happens, it is
2028 * safe to failover the master without data loss.
2029 *
2030 * However modules may generate traffic by calling RedisModule_Call() with
2031 * the "!" flag, or by calling RedisModule_Replicate(), in a context outside
2032 * commands execution, for instance in timeout callbacks, threads safe
2033 * contexts, and so forth. When modules will generate too much traffic, it
2034 * will be hard for the master and replicas offset to match, because there
2035 * is more data to send in the replication channel.
2036 *
2037 * So modules may want to try to avoid very heavy background work that has
2038 * the effect of creating data to the replication channel, when this function
2039 * returns true. This is mostly useful for modules that have background
2040 * garbage collection tasks, or that do writes and replicate such writes
2041 * periodically in timer callbacks or other periodic callbacks.
2042 */
RM_AvoidReplicaTraffic()2043 int RM_AvoidReplicaTraffic() {
2044 return clientsArePaused();
2045 }
2046
2047 /* Change the currently selected DB. Returns an error if the id
2048 * is out of range.
2049 *
2050 * Note that the client will retain the currently selected DB even after
2051 * the Redis command implemented by the module calling this function
2052 * returns.
2053 *
2054 * If the module command wishes to change something in a different DB and
2055 * returns back to the original one, it should call RedisModule_GetSelectedDb()
2056 * before in order to restore the old DB number before returning. */
RM_SelectDb(RedisModuleCtx * ctx,int newid)2057 int RM_SelectDb(RedisModuleCtx *ctx, int newid) {
2058 int retval = selectDb(ctx->client,newid);
2059 return (retval == C_OK) ? REDISMODULE_OK : REDISMODULE_ERR;
2060 }
2061
2062 /* Initialize a RedisModuleKey struct */
moduleInitKey(RedisModuleKey * kp,RedisModuleCtx * ctx,robj * keyname,robj * value,int mode)2063 static void moduleInitKey(RedisModuleKey *kp, RedisModuleCtx *ctx, robj *keyname, robj *value, int mode){
2064 kp->ctx = ctx;
2065 kp->db = ctx->client->db;
2066 kp->key = keyname;
2067 incrRefCount(keyname);
2068 kp->value = value;
2069 kp->iter = NULL;
2070 kp->mode = mode;
2071 zsetKeyReset(kp);
2072 }
2073
2074 /* Return an handle representing a Redis key, so that it is possible
2075 * to call other APIs with the key handle as argument to perform
2076 * operations on the key.
2077 *
2078 * The return value is the handle representing the key, that must be
2079 * closed with RM_CloseKey().
2080 *
2081 * If the key does not exist and WRITE mode is requested, the handle
2082 * is still returned, since it is possible to perform operations on
2083 * a yet not existing key (that will be created, for example, after
2084 * a list push operation). If the mode is just READ instead, and the
2085 * key does not exist, NULL is returned. However it is still safe to
2086 * call RedisModule_CloseKey() and RedisModule_KeyType() on a NULL
2087 * value. */
RM_OpenKey(RedisModuleCtx * ctx,robj * keyname,int mode)2088 void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
2089 RedisModuleKey *kp;
2090 robj *value;
2091 int flags = mode & REDISMODULE_OPEN_KEY_NOTOUCH? LOOKUP_NOTOUCH: 0;
2092
2093 if (mode & REDISMODULE_WRITE) {
2094 value = lookupKeyWriteWithFlags(ctx->client->db,keyname, flags);
2095 } else {
2096 value = lookupKeyReadWithFlags(ctx->client->db,keyname, flags);
2097 if (value == NULL) {
2098 return NULL;
2099 }
2100 }
2101
2102 /* Setup the key handle. */
2103 kp = zmalloc(sizeof(*kp));
2104 moduleInitKey(kp, ctx, keyname, value, mode);
2105 autoMemoryAdd(ctx,REDISMODULE_AM_KEY,kp);
2106 return (void*)kp;
2107 }
2108
2109 /* Destroy a RedisModuleKey struct (freeing is the responsibility of the caller). */
moduleCloseKey(RedisModuleKey * key)2110 static void moduleCloseKey(RedisModuleKey *key) {
2111 int signal = SHOULD_SIGNAL_MODIFIED_KEYS(key->ctx);
2112 if ((key->mode & REDISMODULE_WRITE) && signal)
2113 signalModifiedKey(key->ctx->client,key->db,key->key);
2114 /* TODO: if (key->iter) RM_KeyIteratorStop(kp); */
2115 RM_ZsetRangeStop(key);
2116 decrRefCount(key->key);
2117 }
2118
2119 /* Close a key handle. */
RM_CloseKey(RedisModuleKey * key)2120 void RM_CloseKey(RedisModuleKey *key) {
2121 if (key == NULL) return;
2122 moduleCloseKey(key);
2123 autoMemoryFreed(key->ctx,REDISMODULE_AM_KEY,key);
2124 zfree(key);
2125 }
2126
2127 /* Return the type of the key. If the key pointer is NULL then
2128 * REDISMODULE_KEYTYPE_EMPTY is returned. */
RM_KeyType(RedisModuleKey * key)2129 int RM_KeyType(RedisModuleKey *key) {
2130 if (key == NULL || key->value == NULL) return REDISMODULE_KEYTYPE_EMPTY;
2131 /* We map between defines so that we are free to change the internal
2132 * defines as desired. */
2133 switch(key->value->type) {
2134 case OBJ_STRING: return REDISMODULE_KEYTYPE_STRING;
2135 case OBJ_LIST: return REDISMODULE_KEYTYPE_LIST;
2136 case OBJ_SET: return REDISMODULE_KEYTYPE_SET;
2137 case OBJ_ZSET: return REDISMODULE_KEYTYPE_ZSET;
2138 case OBJ_HASH: return REDISMODULE_KEYTYPE_HASH;
2139 case OBJ_MODULE: return REDISMODULE_KEYTYPE_MODULE;
2140 case OBJ_STREAM: return REDISMODULE_KEYTYPE_STREAM;
2141 default: return REDISMODULE_KEYTYPE_EMPTY;
2142 }
2143 }
2144
2145 /* Return the length of the value associated with the key.
2146 * For strings this is the length of the string. For all the other types
2147 * is the number of elements (just counting keys for hashes).
2148 *
2149 * If the key pointer is NULL or the key is empty, zero is returned. */
RM_ValueLength(RedisModuleKey * key)2150 size_t RM_ValueLength(RedisModuleKey *key) {
2151 if (key == NULL || key->value == NULL) return 0;
2152 switch(key->value->type) {
2153 case OBJ_STRING: return stringObjectLen(key->value);
2154 case OBJ_LIST: return listTypeLength(key->value);
2155 case OBJ_SET: return setTypeSize(key->value);
2156 case OBJ_ZSET: return zsetLength(key->value);
2157 case OBJ_HASH: return hashTypeLength(key->value);
2158 case OBJ_STREAM: return streamLength(key->value);
2159 default: return 0;
2160 }
2161 }
2162
2163 /* If the key is open for writing, remove it, and setup the key to
2164 * accept new writes as an empty key (that will be created on demand).
2165 * On success REDISMODULE_OK is returned. If the key is not open for
2166 * writing REDISMODULE_ERR is returned. */
RM_DeleteKey(RedisModuleKey * key)2167 int RM_DeleteKey(RedisModuleKey *key) {
2168 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
2169 if (key->value) {
2170 dbDelete(key->db,key->key);
2171 key->value = NULL;
2172 }
2173 return REDISMODULE_OK;
2174 }
2175
2176 /* If the key is open for writing, unlink it (that is delete it in a
2177 * non-blocking way, not reclaiming memory immediately) and setup the key to
2178 * accept new writes as an empty key (that will be created on demand).
2179 * On success REDISMODULE_OK is returned. If the key is not open for
2180 * writing REDISMODULE_ERR is returned. */
RM_UnlinkKey(RedisModuleKey * key)2181 int RM_UnlinkKey(RedisModuleKey *key) {
2182 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
2183 if (key->value) {
2184 dbAsyncDelete(key->db,key->key);
2185 key->value = NULL;
2186 }
2187 return REDISMODULE_OK;
2188 }
2189
2190 /* Return the key expire value, as milliseconds of remaining TTL.
2191 * If no TTL is associated with the key or if the key is empty,
2192 * REDISMODULE_NO_EXPIRE is returned. */
RM_GetExpire(RedisModuleKey * key)2193 mstime_t RM_GetExpire(RedisModuleKey *key) {
2194 mstime_t expire = getExpire(key->db,key->key);
2195 if (expire == -1 || key->value == NULL)
2196 return REDISMODULE_NO_EXPIRE;
2197 expire -= mstime();
2198 return expire >= 0 ? expire : 0;
2199 }
2200
2201 /* Set a new expire for the key. If the special expire
2202 * REDISMODULE_NO_EXPIRE is set, the expire is cancelled if there was
2203 * one (the same as the PERSIST command).
2204 *
2205 * Note that the expire must be provided as a positive integer representing
2206 * the number of milliseconds of TTL the key should have.
2207 *
2208 * The function returns REDISMODULE_OK on success or REDISMODULE_ERR if
2209 * the key was not open for writing or is an empty key. */
RM_SetExpire(RedisModuleKey * key,mstime_t expire)2210 int RM_SetExpire(RedisModuleKey *key, mstime_t expire) {
2211 if (!(key->mode & REDISMODULE_WRITE) || key->value == NULL)
2212 return REDISMODULE_ERR;
2213 if (expire != REDISMODULE_NO_EXPIRE) {
2214 expire += mstime();
2215 setExpire(key->ctx->client,key->db,key->key,expire);
2216 } else {
2217 removeExpire(key->db,key->key);
2218 }
2219 return REDISMODULE_OK;
2220 }
2221
2222 /* Performs similar operation to FLUSHALL, and optionally start a new AOF file (if enabled)
2223 * If restart_aof is true, you must make sure the command that triggered this call is not
2224 * propagated to the AOF file.
2225 * When async is set to true, db contents will be freed by a background thread. */
RM_ResetDataset(int restart_aof,int async)2226 void RM_ResetDataset(int restart_aof, int async) {
2227 if (restart_aof && server.aof_state != AOF_OFF) stopAppendOnly();
2228 flushAllDataAndResetRDB(async? EMPTYDB_ASYNC: EMPTYDB_NO_FLAGS);
2229 if (server.aof_enabled && restart_aof) restartAOFAfterSYNC();
2230 }
2231
2232 /* Returns the number of keys in the current db. */
RM_DbSize(RedisModuleCtx * ctx)2233 unsigned long long RM_DbSize(RedisModuleCtx *ctx) {
2234 return dictSize(ctx->client->db->dict);
2235 }
2236
2237 /* Returns a name of a random key, or NULL if current db is empty. */
RM_RandomKey(RedisModuleCtx * ctx)2238 RedisModuleString *RM_RandomKey(RedisModuleCtx *ctx) {
2239 robj *key = dbRandomKey(ctx->client->db);
2240 autoMemoryAdd(ctx,REDISMODULE_AM_STRING,key);
2241 return key;
2242 }
2243
2244 /* --------------------------------------------------------------------------
2245 * Key API for String type
2246 * -------------------------------------------------------------------------- */
2247
2248 /* If the key is open for writing, set the specified string 'str' as the
2249 * value of the key, deleting the old value if any.
2250 * On success REDISMODULE_OK is returned. If the key is not open for
2251 * writing or there is an active iterator, REDISMODULE_ERR is returned. */
RM_StringSet(RedisModuleKey * key,RedisModuleString * str)2252 int RM_StringSet(RedisModuleKey *key, RedisModuleString *str) {
2253 if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR;
2254 RM_DeleteKey(key);
2255 genericSetKey(key->ctx->client,key->db,key->key,str,0,0);
2256 key->value = str;
2257 return REDISMODULE_OK;
2258 }
2259
2260 /* Prepare the key associated string value for DMA access, and returns
2261 * a pointer and size (by reference), that the user can use to read or
2262 * modify the string in-place accessing it directly via pointer.
2263 *
2264 * The 'mode' is composed by bitwise OR-ing the following flags:
2265 *
2266 * REDISMODULE_READ -- Read access
2267 * REDISMODULE_WRITE -- Write access
2268 *
2269 * If the DMA is not requested for writing, the pointer returned should
2270 * only be accessed in a read-only fashion.
2271 *
2272 * On error (wrong type) NULL is returned.
2273 *
2274 * DMA access rules:
2275 *
2276 * 1. No other key writing function should be called since the moment
2277 * the pointer is obtained, for all the time we want to use DMA access
2278 * to read or modify the string.
2279 *
2280 * 2. Each time RM_StringTruncate() is called, to continue with the DMA
2281 * access, RM_StringDMA() should be called again to re-obtain
2282 * a new pointer and length.
2283 *
2284 * 3. If the returned pointer is not NULL, but the length is zero, no
2285 * byte can be touched (the string is empty, or the key itself is empty)
2286 * so a RM_StringTruncate() call should be used if there is to enlarge
2287 * the string, and later call StringDMA() again to get the pointer.
2288 */
RM_StringDMA(RedisModuleKey * key,size_t * len,int mode)2289 char *RM_StringDMA(RedisModuleKey *key, size_t *len, int mode) {
2290 /* We need to return *some* pointer for empty keys, we just return
2291 * a string literal pointer, that is the advantage to be mapped into
2292 * a read only memory page, so the module will segfault if a write
2293 * attempt is performed. */
2294 char *emptystring = "<dma-empty-string>";
2295 if (key->value == NULL) {
2296 *len = 0;
2297 return emptystring;
2298 }
2299
2300 if (key->value->type != OBJ_STRING) return NULL;
2301
2302 /* For write access, and even for read access if the object is encoded,
2303 * we unshare the string (that has the side effect of decoding it). */
2304 if ((mode & REDISMODULE_WRITE) || key->value->encoding != OBJ_ENCODING_RAW)
2305 key->value = dbUnshareStringValue(key->db, key->key, key->value);
2306
2307 *len = sdslen(key->value->ptr);
2308 return key->value->ptr;
2309 }
2310
2311 /* If the string is open for writing and is of string type, resize it, padding
2312 * with zero bytes if the new length is greater than the old one.
2313 *
2314 * After this call, RM_StringDMA() must be called again to continue
2315 * DMA access with the new pointer.
2316 *
2317 * The function returns REDISMODULE_OK on success, and REDISMODULE_ERR on
2318 * error, that is, the key is not open for writing, is not a string
2319 * or resizing for more than 512 MB is requested.
2320 *
2321 * If the key is empty, a string key is created with the new string value
2322 * unless the new length value requested is zero. */
RM_StringTruncate(RedisModuleKey * key,size_t newlen)2323 int RM_StringTruncate(RedisModuleKey *key, size_t newlen) {
2324 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
2325 if (key->value && key->value->type != OBJ_STRING) return REDISMODULE_ERR;
2326 if (newlen > 512*1024*1024) return REDISMODULE_ERR;
2327
2328 /* Empty key and new len set to 0. Just return REDISMODULE_OK without
2329 * doing anything. */
2330 if (key->value == NULL && newlen == 0) return REDISMODULE_OK;
2331
2332 if (key->value == NULL) {
2333 /* Empty key: create it with the new size. */
2334 robj *o = createObject(OBJ_STRING,sdsnewlen(NULL, newlen));
2335 genericSetKey(key->ctx->client,key->db,key->key,o,0,0);
2336 key->value = o;
2337 decrRefCount(o);
2338 } else {
2339 /* Unshare and resize. */
2340 key->value = dbUnshareStringValue(key->db, key->key, key->value);
2341 size_t curlen = sdslen(key->value->ptr);
2342 if (newlen > curlen) {
2343 key->value->ptr = sdsgrowzero(key->value->ptr,newlen);
2344 } else if (newlen < curlen) {
2345 sdsrange(key->value->ptr,0,newlen-1);
2346 /* If the string is too wasteful, reallocate it. */
2347 if (sdslen(key->value->ptr) < sdsavail(key->value->ptr))
2348 key->value->ptr = sdsRemoveFreeSpace(key->value->ptr);
2349 }
2350 }
2351 return REDISMODULE_OK;
2352 }
2353
2354 /* --------------------------------------------------------------------------
2355 * Key API for List type
2356 * -------------------------------------------------------------------------- */
2357
2358 /* Push an element into a list, on head or tail depending on 'where' argument.
2359 * If the key pointer is about an empty key opened for writing, the key
2360 * is created. On error (key opened for read-only operations or of the wrong
2361 * type) REDISMODULE_ERR is returned, otherwise REDISMODULE_OK is returned. */
RM_ListPush(RedisModuleKey * key,int where,RedisModuleString * ele)2362 int RM_ListPush(RedisModuleKey *key, int where, RedisModuleString *ele) {
2363 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
2364 if (key->value && key->value->type != OBJ_LIST) return REDISMODULE_ERR;
2365 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_LIST);
2366 listTypePush(key->value, ele,
2367 (where == REDISMODULE_LIST_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL);
2368 return REDISMODULE_OK;
2369 }
2370
2371 /* Pop an element from the list, and returns it as a module string object
2372 * that the user should be free with RM_FreeString() or by enabling
2373 * automatic memory. 'where' specifies if the element should be popped from
2374 * head or tail. The command returns NULL if:
2375 * 1) The list is empty.
2376 * 2) The key was not open for writing.
2377 * 3) The key is not a list. */
RM_ListPop(RedisModuleKey * key,int where)2378 RedisModuleString *RM_ListPop(RedisModuleKey *key, int where) {
2379 if (!(key->mode & REDISMODULE_WRITE) ||
2380 key->value == NULL ||
2381 key->value->type != OBJ_LIST) return NULL;
2382 robj *ele = listTypePop(key->value,
2383 (where == REDISMODULE_LIST_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL);
2384 robj *decoded = getDecodedObject(ele);
2385 decrRefCount(ele);
2386 moduleDelKeyIfEmpty(key);
2387 autoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,decoded);
2388 return decoded;
2389 }
2390
2391 /* --------------------------------------------------------------------------
2392 * Key API for Sorted Set type
2393 * -------------------------------------------------------------------------- */
2394
2395 /* Conversion from/to public flags of the Modules API and our private flags,
2396 * so that we have everything decoupled. */
RM_ZsetAddFlagsToCoreFlags(int flags)2397 int RM_ZsetAddFlagsToCoreFlags(int flags) {
2398 int retflags = 0;
2399 if (flags & REDISMODULE_ZADD_XX) retflags |= ZADD_XX;
2400 if (flags & REDISMODULE_ZADD_NX) retflags |= ZADD_NX;
2401 return retflags;
2402 }
2403
2404 /* See previous function comment. */
RM_ZsetAddFlagsFromCoreFlags(int flags)2405 int RM_ZsetAddFlagsFromCoreFlags(int flags) {
2406 int retflags = 0;
2407 if (flags & ZADD_ADDED) retflags |= REDISMODULE_ZADD_ADDED;
2408 if (flags & ZADD_UPDATED) retflags |= REDISMODULE_ZADD_UPDATED;
2409 if (flags & ZADD_NOP) retflags |= REDISMODULE_ZADD_NOP;
2410 return retflags;
2411 }
2412
2413 /* Add a new element into a sorted set, with the specified 'score'.
2414 * If the element already exists, the score is updated.
2415 *
2416 * A new sorted set is created at value if the key is an empty open key
2417 * setup for writing.
2418 *
2419 * Additional flags can be passed to the function via a pointer, the flags
2420 * are both used to receive input and to communicate state when the function
2421 * returns. 'flagsptr' can be NULL if no special flags are used.
2422 *
2423 * The input flags are:
2424 *
2425 * REDISMODULE_ZADD_XX: Element must already exist. Do nothing otherwise.
2426 * REDISMODULE_ZADD_NX: Element must not exist. Do nothing otherwise.
2427 *
2428 * The output flags are:
2429 *
2430 * REDISMODULE_ZADD_ADDED: The new element was added to the sorted set.
2431 * REDISMODULE_ZADD_UPDATED: The score of the element was updated.
2432 * REDISMODULE_ZADD_NOP: No operation was performed because XX or NX flags.
2433 *
2434 * On success the function returns REDISMODULE_OK. On the following errors
2435 * REDISMODULE_ERR is returned:
2436 *
2437 * * The key was not opened for writing.
2438 * * The key is of the wrong type.
2439 * * 'score' double value is not a number (NaN).
2440 */
RM_ZsetAdd(RedisModuleKey * key,double score,RedisModuleString * ele,int * flagsptr)2441 int RM_ZsetAdd(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr) {
2442 int flags = 0;
2443 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
2444 if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
2445 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET);
2446 if (flagsptr) flags = RM_ZsetAddFlagsToCoreFlags(*flagsptr);
2447 if (zsetAdd(key->value,score,ele->ptr,&flags,NULL) == 0) {
2448 if (flagsptr) *flagsptr = 0;
2449 return REDISMODULE_ERR;
2450 }
2451 if (flagsptr) *flagsptr = RM_ZsetAddFlagsFromCoreFlags(flags);
2452 return REDISMODULE_OK;
2453 }
2454
2455 /* This function works exactly like RM_ZsetAdd(), but instead of setting
2456 * a new score, the score of the existing element is incremented, or if the
2457 * element does not already exist, it is added assuming the old score was
2458 * zero.
2459 *
2460 * The input and output flags, and the return value, have the same exact
2461 * meaning, with the only difference that this function will return
2462 * REDISMODULE_ERR even when 'score' is a valid double number, but adding it
2463 * to the existing score results into a NaN (not a number) condition.
2464 *
2465 * This function has an additional field 'newscore', if not NULL is filled
2466 * with the new score of the element after the increment, if no error
2467 * is returned. */
RM_ZsetIncrby(RedisModuleKey * key,double score,RedisModuleString * ele,int * flagsptr,double * newscore)2468 int RM_ZsetIncrby(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr, double *newscore) {
2469 int flags = 0;
2470 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
2471 if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
2472 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET);
2473 if (flagsptr) flags = RM_ZsetAddFlagsToCoreFlags(*flagsptr);
2474 flags |= ZADD_INCR;
2475 if (zsetAdd(key->value,score,ele->ptr,&flags,newscore) == 0) {
2476 if (flagsptr) *flagsptr = 0;
2477 return REDISMODULE_ERR;
2478 }
2479 /* zsetAdd() may signal back that the resulting score is not a number. */
2480 if (flagsptr && (*flagsptr & ZADD_NAN)) {
2481 *flagsptr = 0;
2482 return REDISMODULE_ERR;
2483 }
2484 if (flagsptr) *flagsptr = RM_ZsetAddFlagsFromCoreFlags(flags);
2485 return REDISMODULE_OK;
2486 }
2487
2488 /* Remove the specified element from the sorted set.
2489 * The function returns REDISMODULE_OK on success, and REDISMODULE_ERR
2490 * on one of the following conditions:
2491 *
2492 * * The key was not opened for writing.
2493 * * The key is of the wrong type.
2494 *
2495 * The return value does NOT indicate the fact the element was really
2496 * removed (since it existed) or not, just if the function was executed
2497 * with success.
2498 *
2499 * In order to know if the element was removed, the additional argument
2500 * 'deleted' must be passed, that populates the integer by reference
2501 * setting it to 1 or 0 depending on the outcome of the operation.
2502 * The 'deleted' argument can be NULL if the caller is not interested
2503 * to know if the element was really removed.
2504 *
2505 * Empty keys will be handled correctly by doing nothing. */
RM_ZsetRem(RedisModuleKey * key,RedisModuleString * ele,int * deleted)2506 int RM_ZsetRem(RedisModuleKey *key, RedisModuleString *ele, int *deleted) {
2507 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
2508 if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
2509 if (key->value != NULL && zsetDel(key->value,ele->ptr)) {
2510 if (deleted) *deleted = 1;
2511 moduleDelKeyIfEmpty(key);
2512 } else {
2513 if (deleted) *deleted = 0;
2514 }
2515 return REDISMODULE_OK;
2516 }
2517
2518 /* On success retrieve the double score associated at the sorted set element
2519 * 'ele' and returns REDISMODULE_OK. Otherwise REDISMODULE_ERR is returned
2520 * to signal one of the following conditions:
2521 *
2522 * * There is no such element 'ele' in the sorted set.
2523 * * The key is not a sorted set.
2524 * * The key is an open empty key.
2525 */
RM_ZsetScore(RedisModuleKey * key,RedisModuleString * ele,double * score)2526 int RM_ZsetScore(RedisModuleKey *key, RedisModuleString *ele, double *score) {
2527 if (key->value == NULL) return REDISMODULE_ERR;
2528 if (key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
2529 if (zsetScore(key->value,ele->ptr,score) == C_ERR) return REDISMODULE_ERR;
2530 return REDISMODULE_OK;
2531 }
2532
2533 /* --------------------------------------------------------------------------
2534 * Key API for Sorted Set iterator
2535 * -------------------------------------------------------------------------- */
2536
zsetKeyReset(RedisModuleKey * key)2537 void zsetKeyReset(RedisModuleKey *key) {
2538 key->ztype = REDISMODULE_ZSET_RANGE_NONE;
2539 key->zcurrent = NULL;
2540 key->zer = 1;
2541 }
2542
2543 /* Stop a sorted set iteration. */
RM_ZsetRangeStop(RedisModuleKey * key)2544 void RM_ZsetRangeStop(RedisModuleKey *key) {
2545 /* Free resources if needed. */
2546 if (key->ztype == REDISMODULE_ZSET_RANGE_LEX)
2547 zslFreeLexRange(&key->zlrs);
2548 /* Setup sensible values so that misused iteration API calls when an
2549 * iterator is not active will result into something more sensible
2550 * than crashing. */
2551 zsetKeyReset(key);
2552 }
2553
2554 /* Return the "End of range" flag value to signal the end of the iteration. */
RM_ZsetRangeEndReached(RedisModuleKey * key)2555 int RM_ZsetRangeEndReached(RedisModuleKey *key) {
2556 if (!key->value || key->value->type != OBJ_ZSET) return 1;
2557 return key->zer;
2558 }
2559
2560 /* Helper function for RM_ZsetFirstInScoreRange() and RM_ZsetLastInScoreRange().
2561 * Setup the sorted set iteration according to the specified score range
2562 * (see the functions calling it for more info). If 'first' is true the
2563 * first element in the range is used as a starting point for the iterator
2564 * otherwise the last. Return REDISMODULE_OK on success otherwise
2565 * REDISMODULE_ERR. */
zsetInitScoreRange(RedisModuleKey * key,double min,double max,int minex,int maxex,int first)2566 int zsetInitScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex, int first) {
2567 if (!key->value || key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
2568
2569 RM_ZsetRangeStop(key);
2570 key->ztype = REDISMODULE_ZSET_RANGE_SCORE;
2571 key->zer = 0;
2572
2573 /* Setup the range structure used by the sorted set core implementation
2574 * in order to seek at the specified element. */
2575 zrangespec *zrs = &key->zrs;
2576 zrs->min = min;
2577 zrs->max = max;
2578 zrs->minex = minex;
2579 zrs->maxex = maxex;
2580
2581 if (key->value->encoding == OBJ_ENCODING_ZIPLIST) {
2582 key->zcurrent = first ? zzlFirstInRange(key->value->ptr,zrs) :
2583 zzlLastInRange(key->value->ptr,zrs);
2584 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
2585 zset *zs = key->value->ptr;
2586 zskiplist *zsl = zs->zsl;
2587 key->zcurrent = first ? zslFirstInRange(zsl,zrs) :
2588 zslLastInRange(zsl,zrs);
2589 } else {
2590 serverPanic("Unsupported zset encoding");
2591 }
2592 if (key->zcurrent == NULL) key->zer = 1;
2593 return REDISMODULE_OK;
2594 }
2595
2596 /* Setup a sorted set iterator seeking the first element in the specified
2597 * range. Returns REDISMODULE_OK if the iterator was correctly initialized
2598 * otherwise REDISMODULE_ERR is returned in the following conditions:
2599 *
2600 * 1. The value stored at key is not a sorted set or the key is empty.
2601 *
2602 * The range is specified according to the two double values 'min' and 'max'.
2603 * Both can be infinite using the following two macros:
2604 *
2605 * REDISMODULE_POSITIVE_INFINITE for positive infinite value
2606 * REDISMODULE_NEGATIVE_INFINITE for negative infinite value
2607 *
2608 * 'minex' and 'maxex' parameters, if true, respectively setup a range
2609 * where the min and max value are exclusive (not included) instead of
2610 * inclusive. */
RM_ZsetFirstInScoreRange(RedisModuleKey * key,double min,double max,int minex,int maxex)2611 int RM_ZsetFirstInScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex) {
2612 return zsetInitScoreRange(key,min,max,minex,maxex,1);
2613 }
2614
2615 /* Exactly like RedisModule_ZsetFirstInScoreRange() but the last element of
2616 * the range is selected for the start of the iteration instead. */
RM_ZsetLastInScoreRange(RedisModuleKey * key,double min,double max,int minex,int maxex)2617 int RM_ZsetLastInScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex) {
2618 return zsetInitScoreRange(key,min,max,minex,maxex,0);
2619 }
2620
2621 /* Helper function for RM_ZsetFirstInLexRange() and RM_ZsetLastInLexRange().
2622 * Setup the sorted set iteration according to the specified lexicographical
2623 * range (see the functions calling it for more info). If 'first' is true the
2624 * first element in the range is used as a starting point for the iterator
2625 * otherwise the last. Return REDISMODULE_OK on success otherwise
2626 * REDISMODULE_ERR.
2627 *
2628 * Note that this function takes 'min' and 'max' in the same form of the
2629 * Redis ZRANGEBYLEX command. */
zsetInitLexRange(RedisModuleKey * key,RedisModuleString * min,RedisModuleString * max,int first)2630 int zsetInitLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max, int first) {
2631 if (!key->value || key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
2632
2633 RM_ZsetRangeStop(key);
2634 key->zer = 0;
2635
2636 /* Setup the range structure used by the sorted set core implementation
2637 * in order to seek at the specified element. */
2638 zlexrangespec *zlrs = &key->zlrs;
2639 if (zslParseLexRange(min, max, zlrs) == C_ERR) return REDISMODULE_ERR;
2640
2641 /* Set the range type to lex only after successfully parsing the range,
2642 * otherwise we don't want the zlexrangespec to be freed. */
2643 key->ztype = REDISMODULE_ZSET_RANGE_LEX;
2644
2645 if (key->value->encoding == OBJ_ENCODING_ZIPLIST) {
2646 key->zcurrent = first ? zzlFirstInLexRange(key->value->ptr,zlrs) :
2647 zzlLastInLexRange(key->value->ptr,zlrs);
2648 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
2649 zset *zs = key->value->ptr;
2650 zskiplist *zsl = zs->zsl;
2651 key->zcurrent = first ? zslFirstInLexRange(zsl,zlrs) :
2652 zslLastInLexRange(zsl,zlrs);
2653 } else {
2654 serverPanic("Unsupported zset encoding");
2655 }
2656 if (key->zcurrent == NULL) key->zer = 1;
2657
2658 return REDISMODULE_OK;
2659 }
2660
2661 /* Setup a sorted set iterator seeking the first element in the specified
2662 * lexicographical range. Returns REDISMODULE_OK if the iterator was correctly
2663 * initialized otherwise REDISMODULE_ERR is returned in the
2664 * following conditions:
2665 *
2666 * 1. The value stored at key is not a sorted set or the key is empty.
2667 * 2. The lexicographical range 'min' and 'max' format is invalid.
2668 *
2669 * 'min' and 'max' should be provided as two RedisModuleString objects
2670 * in the same format as the parameters passed to the ZRANGEBYLEX command.
2671 * The function does not take ownership of the objects, so they can be released
2672 * ASAP after the iterator is setup. */
RM_ZsetFirstInLexRange(RedisModuleKey * key,RedisModuleString * min,RedisModuleString * max)2673 int RM_ZsetFirstInLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max) {
2674 return zsetInitLexRange(key,min,max,1);
2675 }
2676
2677 /* Exactly like RedisModule_ZsetFirstInLexRange() but the last element of
2678 * the range is selected for the start of the iteration instead. */
RM_ZsetLastInLexRange(RedisModuleKey * key,RedisModuleString * min,RedisModuleString * max)2679 int RM_ZsetLastInLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max) {
2680 return zsetInitLexRange(key,min,max,0);
2681 }
2682
2683 /* Return the current sorted set element of an active sorted set iterator
2684 * or NULL if the range specified in the iterator does not include any
2685 * element. */
RM_ZsetRangeCurrentElement(RedisModuleKey * key,double * score)2686 RedisModuleString *RM_ZsetRangeCurrentElement(RedisModuleKey *key, double *score) {
2687 RedisModuleString *str;
2688
2689 if (key->zcurrent == NULL) return NULL;
2690 if (key->value->encoding == OBJ_ENCODING_ZIPLIST) {
2691 unsigned char *eptr, *sptr;
2692 eptr = key->zcurrent;
2693 sds ele = ziplistGetObject(eptr);
2694 if (score) {
2695 sptr = ziplistNext(key->value->ptr,eptr);
2696 *score = zzlGetScore(sptr);
2697 }
2698 str = createObject(OBJ_STRING,ele);
2699 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
2700 zskiplistNode *ln = key->zcurrent;
2701 if (score) *score = ln->score;
2702 str = createStringObject(ln->ele,sdslen(ln->ele));
2703 } else {
2704 serverPanic("Unsupported zset encoding");
2705 }
2706 autoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,str);
2707 return str;
2708 }
2709
2710 /* Go to the next element of the sorted set iterator. Returns 1 if there was
2711 * a next element, 0 if we are already at the latest element or the range
2712 * does not include any item at all. */
RM_ZsetRangeNext(RedisModuleKey * key)2713 int RM_ZsetRangeNext(RedisModuleKey *key) {
2714 if (!key->ztype || !key->zcurrent) return 0; /* No active iterator. */
2715
2716 if (key->value->encoding == OBJ_ENCODING_ZIPLIST) {
2717 unsigned char *zl = key->value->ptr;
2718 unsigned char *eptr = key->zcurrent;
2719 unsigned char *next;
2720 next = ziplistNext(zl,eptr); /* Skip element. */
2721 if (next) next = ziplistNext(zl,next); /* Skip score. */
2722 if (next == NULL) {
2723 key->zer = 1;
2724 return 0;
2725 } else {
2726 /* Are we still within the range? */
2727 if (key->ztype == REDISMODULE_ZSET_RANGE_SCORE) {
2728 /* Fetch the next element score for the
2729 * range check. */
2730 unsigned char *saved_next = next;
2731 next = ziplistNext(zl,next); /* Skip next element. */
2732 double score = zzlGetScore(next); /* Obtain the next score. */
2733 if (!zslValueLteMax(score,&key->zrs)) {
2734 key->zer = 1;
2735 return 0;
2736 }
2737 next = saved_next;
2738 } else if (key->ztype == REDISMODULE_ZSET_RANGE_LEX) {
2739 if (!zzlLexValueLteMax(next,&key->zlrs)) {
2740 key->zer = 1;
2741 return 0;
2742 }
2743 }
2744 key->zcurrent = next;
2745 return 1;
2746 }
2747 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
2748 zskiplistNode *ln = key->zcurrent, *next = ln->level[0].forward;
2749 if (next == NULL) {
2750 key->zer = 1;
2751 return 0;
2752 } else {
2753 /* Are we still within the range? */
2754 if (key->ztype == REDISMODULE_ZSET_RANGE_SCORE &&
2755 !zslValueLteMax(next->score,&key->zrs))
2756 {
2757 key->zer = 1;
2758 return 0;
2759 } else if (key->ztype == REDISMODULE_ZSET_RANGE_LEX) {
2760 if (!zslLexValueLteMax(next->ele,&key->zlrs)) {
2761 key->zer = 1;
2762 return 0;
2763 }
2764 }
2765 key->zcurrent = next;
2766 return 1;
2767 }
2768 } else {
2769 serverPanic("Unsupported zset encoding");
2770 }
2771 }
2772
2773 /* Go to the previous element of the sorted set iterator. Returns 1 if there was
2774 * a previous element, 0 if we are already at the first element or the range
2775 * does not include any item at all. */
RM_ZsetRangePrev(RedisModuleKey * key)2776 int RM_ZsetRangePrev(RedisModuleKey *key) {
2777 if (!key->ztype || !key->zcurrent) return 0; /* No active iterator. */
2778
2779 if (key->value->encoding == OBJ_ENCODING_ZIPLIST) {
2780 unsigned char *zl = key->value->ptr;
2781 unsigned char *eptr = key->zcurrent;
2782 unsigned char *prev;
2783 prev = ziplistPrev(zl,eptr); /* Go back to previous score. */
2784 if (prev) prev = ziplistPrev(zl,prev); /* Back to previous ele. */
2785 if (prev == NULL) {
2786 key->zer = 1;
2787 return 0;
2788 } else {
2789 /* Are we still within the range? */
2790 if (key->ztype == REDISMODULE_ZSET_RANGE_SCORE) {
2791 /* Fetch the previous element score for the
2792 * range check. */
2793 unsigned char *saved_prev = prev;
2794 prev = ziplistNext(zl,prev); /* Skip element to get the score.*/
2795 double score = zzlGetScore(prev); /* Obtain the prev score. */
2796 if (!zslValueGteMin(score,&key->zrs)) {
2797 key->zer = 1;
2798 return 0;
2799 }
2800 prev = saved_prev;
2801 } else if (key->ztype == REDISMODULE_ZSET_RANGE_LEX) {
2802 if (!zzlLexValueGteMin(prev,&key->zlrs)) {
2803 key->zer = 1;
2804 return 0;
2805 }
2806 }
2807 key->zcurrent = prev;
2808 return 1;
2809 }
2810 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
2811 zskiplistNode *ln = key->zcurrent, *prev = ln->backward;
2812 if (prev == NULL) {
2813 key->zer = 1;
2814 return 0;
2815 } else {
2816 /* Are we still within the range? */
2817 if (key->ztype == REDISMODULE_ZSET_RANGE_SCORE &&
2818 !zslValueGteMin(prev->score,&key->zrs))
2819 {
2820 key->zer = 1;
2821 return 0;
2822 } else if (key->ztype == REDISMODULE_ZSET_RANGE_LEX) {
2823 if (!zslLexValueGteMin(prev->ele,&key->zlrs)) {
2824 key->zer = 1;
2825 return 0;
2826 }
2827 }
2828 key->zcurrent = prev;
2829 return 1;
2830 }
2831 } else {
2832 serverPanic("Unsupported zset encoding");
2833 }
2834 }
2835
2836 /* --------------------------------------------------------------------------
2837 * Key API for Hash type
2838 * -------------------------------------------------------------------------- */
2839
2840 /* Set the field of the specified hash field to the specified value.
2841 * If the key is an empty key open for writing, it is created with an empty
2842 * hash value, in order to set the specified field.
2843 *
2844 * The function is variadic and the user must specify pairs of field
2845 * names and values, both as RedisModuleString pointers (unless the
2846 * CFIELD option is set, see later). At the end of the field/value-ptr pairs,
2847 * NULL must be specified as last argument to signal the end of the arguments
2848 * in the variadic function.
2849 *
2850 * Example to set the hash argv[1] to the value argv[2]:
2851 *
2852 * RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[1],argv[2],NULL);
2853 *
2854 * The function can also be used in order to delete fields (if they exist)
2855 * by setting them to the specified value of REDISMODULE_HASH_DELETE:
2856 *
2857 * RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[1],
2858 * REDISMODULE_HASH_DELETE,NULL);
2859 *
2860 * The behavior of the command changes with the specified flags, that can be
2861 * set to REDISMODULE_HASH_NONE if no special behavior is needed.
2862 *
2863 * REDISMODULE_HASH_NX: The operation is performed only if the field was not
2864 * already existing in the hash.
2865 * REDISMODULE_HASH_XX: The operation is performed only if the field was
2866 * already existing, so that a new value could be
2867 * associated to an existing filed, but no new fields
2868 * are created.
2869 * REDISMODULE_HASH_CFIELDS: The field names passed are null terminated C
2870 * strings instead of RedisModuleString objects.
2871 *
2872 * Unless NX is specified, the command overwrites the old field value with
2873 * the new one.
2874 *
2875 * When using REDISMODULE_HASH_CFIELDS, field names are reported using
2876 * normal C strings, so for example to delete the field "foo" the following
2877 * code can be used:
2878 *
2879 * RedisModule_HashSet(key,REDISMODULE_HASH_CFIELDS,"foo",
2880 * REDISMODULE_HASH_DELETE,NULL);
2881 *
2882 * Return value:
2883 *
2884 * The number of fields updated (that may be less than the number of fields
2885 * specified because of the XX or NX options).
2886 *
2887 * In the following case the return value is always zero:
2888 *
2889 * * The key was not open for writing.
2890 * * The key was associated with a non Hash value.
2891 */
RM_HashSet(RedisModuleKey * key,int flags,...)2892 int RM_HashSet(RedisModuleKey *key, int flags, ...) {
2893 va_list ap;
2894 if (!(key->mode & REDISMODULE_WRITE)) return 0;
2895 if (key->value && key->value->type != OBJ_HASH) return 0;
2896 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_HASH);
2897
2898 int updated = 0;
2899 va_start(ap, flags);
2900 while(1) {
2901 RedisModuleString *field, *value;
2902 /* Get the field and value objects. */
2903 if (flags & REDISMODULE_HASH_CFIELDS) {
2904 char *cfield = va_arg(ap,char*);
2905 if (cfield == NULL) break;
2906 field = createRawStringObject(cfield,strlen(cfield));
2907 } else {
2908 field = va_arg(ap,RedisModuleString*);
2909 if (field == NULL) break;
2910 }
2911 value = va_arg(ap,RedisModuleString*);
2912
2913 /* Handle XX and NX */
2914 if (flags & (REDISMODULE_HASH_XX|REDISMODULE_HASH_NX)) {
2915 int exists = hashTypeExists(key->value, field->ptr);
2916 if (((flags & REDISMODULE_HASH_XX) && !exists) ||
2917 ((flags & REDISMODULE_HASH_NX) && exists))
2918 {
2919 if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field);
2920 continue;
2921 }
2922 }
2923
2924 /* Handle deletion if value is REDISMODULE_HASH_DELETE. */
2925 if (value == REDISMODULE_HASH_DELETE) {
2926 updated += hashTypeDelete(key->value, field->ptr);
2927 if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field);
2928 continue;
2929 }
2930
2931 int low_flags = HASH_SET_COPY;
2932 /* If CFIELDS is active, we can pass the ownership of the
2933 * SDS object to the low level function that sets the field
2934 * to avoid a useless copy. */
2935 if (flags & REDISMODULE_HASH_CFIELDS)
2936 low_flags |= HASH_SET_TAKE_FIELD;
2937
2938 robj *argv[2] = {field,value};
2939 hashTypeTryConversion(key->value,argv,0,1);
2940 updated += hashTypeSet(key->value, field->ptr, value->ptr, low_flags);
2941
2942 /* If CFIELDS is active, SDS string ownership is now of hashTypeSet(),
2943 * however we still have to release the 'field' object shell. */
2944 if (flags & REDISMODULE_HASH_CFIELDS) {
2945 field->ptr = NULL; /* Prevent the SDS string from being freed. */
2946 decrRefCount(field);
2947 }
2948 }
2949 va_end(ap);
2950 moduleDelKeyIfEmpty(key);
2951 return updated;
2952 }
2953
2954 /* Get fields from an hash value. This function is called using a variable
2955 * number of arguments, alternating a field name (as a RedisModuleString
2956 * pointer) with a pointer to a RedisModuleString pointer, that is set to the
2957 * value of the field if the field exists, or NULL if the field does not exist.
2958 * At the end of the field/value-ptr pairs, NULL must be specified as last
2959 * argument to signal the end of the arguments in the variadic function.
2960 *
2961 * This is an example usage:
2962 *
2963 * RedisModuleString *first, *second;
2964 * RedisModule_HashGet(mykey,REDISMODULE_HASH_NONE,argv[1],&first,
2965 * argv[2],&second,NULL);
2966 *
2967 * As with RedisModule_HashSet() the behavior of the command can be specified
2968 * passing flags different than REDISMODULE_HASH_NONE:
2969 *
2970 * REDISMODULE_HASH_CFIELDS: field names as null terminated C strings.
2971 *
2972 * REDISMODULE_HASH_EXISTS: instead of setting the value of the field
2973 * expecting a RedisModuleString pointer to pointer, the function just
2974 * reports if the field exists or not and expects an integer pointer
2975 * as the second element of each pair.
2976 *
2977 * Example of REDISMODULE_HASH_CFIELDS:
2978 *
2979 * RedisModuleString *username, *hashedpass;
2980 * RedisModule_HashGet(mykey,REDISMODULE_HASH_CFIELDS,"username",&username,"hp",&hashedpass, NULL);
2981 *
2982 * Example of REDISMODULE_HASH_EXISTS:
2983 *
2984 * int exists;
2985 * RedisModule_HashGet(mykey,REDISMODULE_HASH_EXISTS,argv[1],&exists,NULL);
2986 *
2987 * The function returns REDISMODULE_OK on success and REDISMODULE_ERR if
2988 * the key is not an hash value.
2989 *
2990 * Memory management:
2991 *
2992 * The returned RedisModuleString objects should be released with
2993 * RedisModule_FreeString(), or by enabling automatic memory management.
2994 */
RM_HashGet(RedisModuleKey * key,int flags,...)2995 int RM_HashGet(RedisModuleKey *key, int flags, ...) {
2996 va_list ap;
2997 if (key->value && key->value->type != OBJ_HASH) return REDISMODULE_ERR;
2998
2999 va_start(ap, flags);
3000 while(1) {
3001 RedisModuleString *field, **valueptr;
3002 int *existsptr;
3003 /* Get the field object and the value pointer to pointer. */
3004 if (flags & REDISMODULE_HASH_CFIELDS) {
3005 char *cfield = va_arg(ap,char*);
3006 if (cfield == NULL) break;
3007 field = createRawStringObject(cfield,strlen(cfield));
3008 } else {
3009 field = va_arg(ap,RedisModuleString*);
3010 if (field == NULL) break;
3011 }
3012
3013 /* Query the hash for existence or value object. */
3014 if (flags & REDISMODULE_HASH_EXISTS) {
3015 existsptr = va_arg(ap,int*);
3016 if (key->value)
3017 *existsptr = hashTypeExists(key->value,field->ptr);
3018 else
3019 *existsptr = 0;
3020 } else {
3021 valueptr = va_arg(ap,RedisModuleString**);
3022 if (key->value) {
3023 *valueptr = hashTypeGetValueObject(key->value,field->ptr);
3024 if (*valueptr) {
3025 robj *decoded = getDecodedObject(*valueptr);
3026 decrRefCount(*valueptr);
3027 *valueptr = decoded;
3028 }
3029 if (*valueptr)
3030 autoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,*valueptr);
3031 } else {
3032 *valueptr = NULL;
3033 }
3034 }
3035
3036 /* Cleanup */
3037 if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field);
3038 }
3039 va_end(ap);
3040 return REDISMODULE_OK;
3041 }
3042
3043 /* --------------------------------------------------------------------------
3044 * Redis <-> Modules generic Call() API
3045 * -------------------------------------------------------------------------- */
3046
3047 /* Create a new RedisModuleCallReply object. The processing of the reply
3048 * is lazy, the object is just populated with the raw protocol and later
3049 * is processed as needed. Initially we just make sure to set the right
3050 * reply type, which is extremely cheap to do. */
moduleCreateCallReplyFromProto(RedisModuleCtx * ctx,sds proto)3051 RedisModuleCallReply *moduleCreateCallReplyFromProto(RedisModuleCtx *ctx, sds proto) {
3052 RedisModuleCallReply *reply = zmalloc(sizeof(*reply));
3053 reply->ctx = ctx;
3054 reply->proto = proto;
3055 reply->protolen = sdslen(proto);
3056 reply->flags = REDISMODULE_REPLYFLAG_TOPARSE; /* Lazy parsing. */
3057 switch(proto[0]) {
3058 case '$':
3059 case '+': reply->type = REDISMODULE_REPLY_STRING; break;
3060 case '-': reply->type = REDISMODULE_REPLY_ERROR; break;
3061 case ':': reply->type = REDISMODULE_REPLY_INTEGER; break;
3062 case '*': reply->type = REDISMODULE_REPLY_ARRAY; break;
3063 default: reply->type = REDISMODULE_REPLY_UNKNOWN; break;
3064 }
3065 if ((proto[0] == '*' || proto[0] == '$') && proto[1] == '-')
3066 reply->type = REDISMODULE_REPLY_NULL;
3067 return reply;
3068 }
3069
3070 void moduleParseCallReply_Int(RedisModuleCallReply *reply);
3071 void moduleParseCallReply_BulkString(RedisModuleCallReply *reply);
3072 void moduleParseCallReply_SimpleString(RedisModuleCallReply *reply);
3073 void moduleParseCallReply_Array(RedisModuleCallReply *reply);
3074
3075 /* Do nothing if REDISMODULE_REPLYFLAG_TOPARSE is false, otherwise
3076 * use the protocol of the reply in reply->proto in order to fill the
3077 * reply with parsed data according to the reply type. */
moduleParseCallReply(RedisModuleCallReply * reply)3078 void moduleParseCallReply(RedisModuleCallReply *reply) {
3079 if (!(reply->flags & REDISMODULE_REPLYFLAG_TOPARSE)) return;
3080 reply->flags &= ~REDISMODULE_REPLYFLAG_TOPARSE;
3081
3082 switch(reply->proto[0]) {
3083 case ':': moduleParseCallReply_Int(reply); break;
3084 case '$': moduleParseCallReply_BulkString(reply); break;
3085 case '-': /* handled by next item. */
3086 case '+': moduleParseCallReply_SimpleString(reply); break;
3087 case '*': moduleParseCallReply_Array(reply); break;
3088 }
3089 }
3090
moduleParseCallReply_Int(RedisModuleCallReply * reply)3091 void moduleParseCallReply_Int(RedisModuleCallReply *reply) {
3092 char *proto = reply->proto;
3093 char *p = strchr(proto+1,'\r');
3094
3095 string2ll(proto+1,p-proto-1,&reply->val.ll);
3096 reply->protolen = p-proto+2;
3097 reply->type = REDISMODULE_REPLY_INTEGER;
3098 }
3099
moduleParseCallReply_BulkString(RedisModuleCallReply * reply)3100 void moduleParseCallReply_BulkString(RedisModuleCallReply *reply) {
3101 char *proto = reply->proto;
3102 char *p = strchr(proto+1,'\r');
3103 long long bulklen;
3104
3105 string2ll(proto+1,p-proto-1,&bulklen);
3106 if (bulklen == -1) {
3107 reply->protolen = p-proto+2;
3108 reply->type = REDISMODULE_REPLY_NULL;
3109 } else {
3110 reply->val.str = p+2;
3111 reply->len = bulklen;
3112 reply->protolen = p-proto+2+bulklen+2;
3113 reply->type = REDISMODULE_REPLY_STRING;
3114 }
3115 }
3116
moduleParseCallReply_SimpleString(RedisModuleCallReply * reply)3117 void moduleParseCallReply_SimpleString(RedisModuleCallReply *reply) {
3118 char *proto = reply->proto;
3119 char *p = strchr(proto+1,'\r');
3120
3121 reply->val.str = proto+1;
3122 reply->len = p-proto-1;
3123 reply->protolen = p-proto+2;
3124 reply->type = proto[0] == '+' ? REDISMODULE_REPLY_STRING :
3125 REDISMODULE_REPLY_ERROR;
3126 }
3127
moduleParseCallReply_Array(RedisModuleCallReply * reply)3128 void moduleParseCallReply_Array(RedisModuleCallReply *reply) {
3129 char *proto = reply->proto;
3130 char *p = strchr(proto+1,'\r');
3131 long long arraylen, j;
3132
3133 string2ll(proto+1,p-proto-1,&arraylen);
3134 p += 2;
3135
3136 if (arraylen == -1) {
3137 reply->protolen = p-proto;
3138 reply->type = REDISMODULE_REPLY_NULL;
3139 return;
3140 }
3141
3142 reply->val.array = zmalloc(sizeof(RedisModuleCallReply)*arraylen);
3143 reply->len = arraylen;
3144 for (j = 0; j < arraylen; j++) {
3145 RedisModuleCallReply *ele = reply->val.array+j;
3146 ele->flags = REDISMODULE_REPLYFLAG_NESTED |
3147 REDISMODULE_REPLYFLAG_TOPARSE;
3148 ele->proto = p;
3149 ele->ctx = reply->ctx;
3150 moduleParseCallReply(ele);
3151 p += ele->protolen;
3152 }
3153 reply->protolen = p-proto;
3154 reply->type = REDISMODULE_REPLY_ARRAY;
3155 }
3156
3157 /* Free a Call reply and all the nested replies it contains if it's an
3158 * array. */
RM_FreeCallReply_Rec(RedisModuleCallReply * reply,int freenested)3159 void RM_FreeCallReply_Rec(RedisModuleCallReply *reply, int freenested){
3160 /* Don't free nested replies by default: the user must always free the
3161 * toplevel reply. However be gentle and don't crash if the module
3162 * misuses the API. */
3163 if (!freenested && reply->flags & REDISMODULE_REPLYFLAG_NESTED) return;
3164
3165 if (!(reply->flags & REDISMODULE_REPLYFLAG_TOPARSE)) {
3166 if (reply->type == REDISMODULE_REPLY_ARRAY) {
3167 size_t j;
3168 for (j = 0; j < reply->len; j++)
3169 RM_FreeCallReply_Rec(reply->val.array+j,1);
3170 zfree(reply->val.array);
3171 }
3172 }
3173
3174 /* For nested replies, we don't free reply->proto (which if not NULL
3175 * references the parent reply->proto buffer), nor the structure
3176 * itself which is allocated as an array of structures, and is freed
3177 * when the array value is released. */
3178 if (!(reply->flags & REDISMODULE_REPLYFLAG_NESTED)) {
3179 if (reply->proto) sdsfree(reply->proto);
3180 zfree(reply);
3181 }
3182 }
3183
3184 /* Wrapper for the recursive free reply function. This is needed in order
3185 * to have the first level function to return on nested replies, but only
3186 * if called by the module API. */
RM_FreeCallReply(RedisModuleCallReply * reply)3187 void RM_FreeCallReply(RedisModuleCallReply *reply) {
3188
3189 RedisModuleCtx *ctx = reply->ctx;
3190 RM_FreeCallReply_Rec(reply,0);
3191 autoMemoryFreed(ctx,REDISMODULE_AM_REPLY,reply);
3192 }
3193
3194 /* Return the reply type. */
RM_CallReplyType(RedisModuleCallReply * reply)3195 int RM_CallReplyType(RedisModuleCallReply *reply) {
3196 if (!reply) return REDISMODULE_REPLY_UNKNOWN;
3197 return reply->type;
3198 }
3199
3200 /* Return the reply type length, where applicable. */
RM_CallReplyLength(RedisModuleCallReply * reply)3201 size_t RM_CallReplyLength(RedisModuleCallReply *reply) {
3202 moduleParseCallReply(reply);
3203 switch(reply->type) {
3204 case REDISMODULE_REPLY_STRING:
3205 case REDISMODULE_REPLY_ERROR:
3206 case REDISMODULE_REPLY_ARRAY:
3207 return reply->len;
3208 default:
3209 return 0;
3210 }
3211 }
3212
3213 /* Return the 'idx'-th nested call reply element of an array reply, or NULL
3214 * if the reply type is wrong or the index is out of range. */
RM_CallReplyArrayElement(RedisModuleCallReply * reply,size_t idx)3215 RedisModuleCallReply *RM_CallReplyArrayElement(RedisModuleCallReply *reply, size_t idx) {
3216 moduleParseCallReply(reply);
3217 if (reply->type != REDISMODULE_REPLY_ARRAY) return NULL;
3218 if (idx >= reply->len) return NULL;
3219 return reply->val.array+idx;
3220 }
3221
3222 /* Return the long long of an integer reply. */
RM_CallReplyInteger(RedisModuleCallReply * reply)3223 long long RM_CallReplyInteger(RedisModuleCallReply *reply) {
3224 moduleParseCallReply(reply);
3225 if (reply->type != REDISMODULE_REPLY_INTEGER) return LLONG_MIN;
3226 return reply->val.ll;
3227 }
3228
3229 /* Return the pointer and length of a string or error reply. */
RM_CallReplyStringPtr(RedisModuleCallReply * reply,size_t * len)3230 const char *RM_CallReplyStringPtr(RedisModuleCallReply *reply, size_t *len) {
3231 moduleParseCallReply(reply);
3232 if (reply->type != REDISMODULE_REPLY_STRING &&
3233 reply->type != REDISMODULE_REPLY_ERROR) return NULL;
3234 if (len) *len = reply->len;
3235 return reply->val.str;
3236 }
3237
3238 /* Return a new string object from a call reply of type string, error or
3239 * integer. Otherwise (wrong reply type) return NULL. */
RM_CreateStringFromCallReply(RedisModuleCallReply * reply)3240 RedisModuleString *RM_CreateStringFromCallReply(RedisModuleCallReply *reply) {
3241 moduleParseCallReply(reply);
3242 switch(reply->type) {
3243 case REDISMODULE_REPLY_STRING:
3244 case REDISMODULE_REPLY_ERROR:
3245 return RM_CreateString(reply->ctx,reply->val.str,reply->len);
3246 case REDISMODULE_REPLY_INTEGER: {
3247 char buf[64];
3248 int len = ll2string(buf,sizeof(buf),reply->val.ll);
3249 return RM_CreateString(reply->ctx,buf,len);
3250 }
3251 default: return NULL;
3252 }
3253 }
3254
3255 /* Returns an array of robj pointers, and populates *argc with the number
3256 * of items, by parsing the format specifier "fmt" as described for
3257 * the RM_Call(), RM_Replicate() and other module APIs.
3258 *
3259 * The integer pointed by 'flags' is populated with flags according
3260 * to special modifiers in "fmt". For now only one exists:
3261 *
3262 * "!" -> REDISMODULE_ARGV_REPLICATE
3263 * "A" -> REDISMODULE_ARGV_NO_AOF
3264 * "R" -> REDISMODULE_ARGV_NO_REPLICAS
3265 *
3266 * On error (format specifier error) NULL is returned and nothing is
3267 * allocated. On success the argument vector is returned. */
moduleCreateArgvFromUserFormat(const char * cmdname,const char * fmt,int * argcp,int * flags,va_list ap)3268 robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *flags, va_list ap) {
3269 int argc = 0, argv_size, j;
3270 robj **argv = NULL;
3271
3272 /* As a first guess to avoid useless reallocations, size argv to
3273 * hold one argument for each char specifier in 'fmt'. */
3274 argv_size = strlen(fmt)+1; /* +1 because of the command name. */
3275 argv = zrealloc(argv,sizeof(robj*)*argv_size);
3276
3277 /* Build the arguments vector based on the format specifier. */
3278 argv[0] = createStringObject(cmdname,strlen(cmdname));
3279 argc++;
3280
3281 /* Create the client and dispatch the command. */
3282 const char *p = fmt;
3283 while(*p) {
3284 if (*p == 'c') {
3285 char *cstr = va_arg(ap,char*);
3286 argv[argc++] = createStringObject(cstr,strlen(cstr));
3287 } else if (*p == 's') {
3288 robj *obj = va_arg(ap,void*);
3289 if (obj->refcount == OBJ_STATIC_REFCOUNT)
3290 obj = createStringObject(obj->ptr,sdslen(obj->ptr));
3291 else
3292 incrRefCount(obj);
3293 argv[argc++] = obj;
3294 } else if (*p == 'b') {
3295 char *buf = va_arg(ap,char*);
3296 size_t len = va_arg(ap,size_t);
3297 argv[argc++] = createStringObject(buf,len);
3298 } else if (*p == 'l') {
3299 long long ll = va_arg(ap,long long);
3300 argv[argc++] = createObject(OBJ_STRING,sdsfromlonglong(ll));
3301 } else if (*p == 'v') {
3302 /* A vector of strings */
3303 robj **v = va_arg(ap, void*);
3304 size_t vlen = va_arg(ap, size_t);
3305
3306 /* We need to grow argv to hold the vector's elements.
3307 * We resize by vector_len-1 elements, because we held
3308 * one element in argv for the vector already */
3309 argv_size += vlen-1;
3310 argv = zrealloc(argv,sizeof(robj*)*argv_size);
3311
3312 size_t i = 0;
3313 for (i = 0; i < vlen; i++) {
3314 incrRefCount(v[i]);
3315 argv[argc++] = v[i];
3316 }
3317 } else if (*p == '!') {
3318 if (flags) (*flags) |= REDISMODULE_ARGV_REPLICATE;
3319 } else if (*p == 'A') {
3320 if (flags) (*flags) |= REDISMODULE_ARGV_NO_AOF;
3321 } else if (*p == 'R') {
3322 if (flags) (*flags) |= REDISMODULE_ARGV_NO_REPLICAS;
3323 } else {
3324 goto fmterr;
3325 }
3326 p++;
3327 }
3328 *argcp = argc;
3329 return argv;
3330
3331 fmterr:
3332 for (j = 0; j < argc; j++)
3333 decrRefCount(argv[j]);
3334 zfree(argv);
3335 return NULL;
3336 }
3337
3338 /* Exported API to call any Redis command from modules.
3339 *
3340 * * **cmdname**: The Redis command to call.
3341 * * **fmt**: A format specifier string for the command's arguments. Each
3342 * of the arguments should be specified by a valid type specification:
3343 * b The argument is a buffer and is immediately followed by another
3344 * argument that is the buffer's length.
3345 * c The argument is a pointer to a plain C string (null-terminated).
3346 * l The argument is long long integer.
3347 * s The argument is a RedisModuleString.
3348 * v The argument(s) is a vector of RedisModuleString.
3349 *
3350 * The format specifier can also include modifiers:
3351 * ! Sends the Redis command and its arguments to replicas and AOF.
3352 * A Suppress AOF propagation, send only to replicas (requires `!`).
3353 * R Suppress replicas propagation, send only to AOF (requires `!`).
3354 * * **...**: The actual arguments to the Redis command.
3355 *
3356 * On success a RedisModuleCallReply object is returned, otherwise
3357 * NULL is returned and errno is set to the following values:
3358 *
3359 * EBADF: wrong format specifier.
3360 * EINVAL: wrong command arity.
3361 * ENOENT: command does not exist.
3362 * EPERM: operation in Cluster instance with key in non local slot.
3363 * EROFS: operation in Cluster instance when a write command is sent
3364 * in a readonly state.
3365 * ENETDOWN: operation in Cluster instance when cluster is down.
3366 *
3367 * Example code fragment:
3368 *
3369 * reply = RedisModule_Call(ctx,"INCRBY","sc",argv[1],"10");
3370 * if (RedisModule_CallReplyType(reply) == REDISMODULE_REPLY_INTEGER) {
3371 * long long myval = RedisModule_CallReplyInteger(reply);
3372 * // Do something with myval.
3373 * }
3374 *
3375 * This API is documented here: https://redis.io/topics/modules-intro
3376 */
RM_Call(RedisModuleCtx * ctx,const char * cmdname,const char * fmt,...)3377 RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
3378 struct redisCommand *cmd;
3379 client *c = NULL;
3380 robj **argv = NULL;
3381 int argc = 0, flags = 0;
3382 va_list ap;
3383 RedisModuleCallReply *reply = NULL;
3384 int replicate = 0; /* Replicate this command? */
3385
3386 /* Create the client and dispatch the command. */
3387 va_start(ap, fmt);
3388 c = createClient(NULL);
3389 c->user = NULL; /* Root user. */
3390 argv = moduleCreateArgvFromUserFormat(cmdname,fmt,&argc,&flags,ap);
3391 replicate = flags & REDISMODULE_ARGV_REPLICATE;
3392 va_end(ap);
3393
3394 /* Setup our fake client for command execution. */
3395 c->flags |= CLIENT_MODULE;
3396 c->db = ctx->client->db;
3397 c->argv = argv;
3398 c->argc = argc;
3399 if (ctx->module) ctx->module->in_call++;
3400
3401 /* We handle the above format error only when the client is setup so that
3402 * we can free it normally. */
3403 if (argv == NULL) {
3404 errno = EBADF;
3405 goto cleanup;
3406 }
3407
3408 /* Call command filters */
3409 moduleCallCommandFilters(c);
3410
3411 /* Lookup command now, after filters had a chance to make modifications
3412 * if necessary.
3413 */
3414 cmd = lookupCommand(c->argv[0]->ptr);
3415 if (!cmd) {
3416 errno = ENOENT;
3417 goto cleanup;
3418 }
3419 c->cmd = c->lastcmd = cmd;
3420
3421 /* Basic arity checks. */
3422 if ((cmd->arity > 0 && cmd->arity != argc) || (argc < -cmd->arity)) {
3423 errno = EINVAL;
3424 goto cleanup;
3425 }
3426
3427 /* If this is a Redis Cluster node, we need to make sure the module is not
3428 * trying to access non-local keys, with the exception of commands
3429 * received from our master. */
3430 if (server.cluster_enabled && !(ctx->client->flags & CLIENT_MASTER)) {
3431 int error_code;
3432 /* Duplicate relevant flags in the module client. */
3433 c->flags &= ~(CLIENT_READONLY|CLIENT_ASKING);
3434 c->flags |= ctx->client->flags & (CLIENT_READONLY|CLIENT_ASKING);
3435 if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,&error_code) !=
3436 server.cluster->myself)
3437 {
3438 if (error_code == CLUSTER_REDIR_DOWN_RO_STATE) {
3439 errno = EROFS;
3440 } else if (error_code == CLUSTER_REDIR_DOWN_STATE) {
3441 errno = ENETDOWN;
3442 } else {
3443 errno = EPERM;
3444 }
3445 goto cleanup;
3446 }
3447 }
3448
3449 /* If we are using single commands replication, we need to wrap what
3450 * we propagate into a MULTI/EXEC block, so that it will be atomic like
3451 * a Lua script in the context of AOF and slaves. */
3452 if (replicate) moduleReplicateMultiIfNeeded(ctx);
3453
3454 /* Run the command */
3455 int call_flags = CMD_CALL_SLOWLOG | CMD_CALL_STATS | CMD_CALL_NOWRAP;
3456 if (replicate) {
3457 if (!(flags & REDISMODULE_ARGV_NO_AOF))
3458 call_flags |= CMD_CALL_PROPAGATE_AOF;
3459 if (!(flags & REDISMODULE_ARGV_NO_REPLICAS))
3460 call_flags |= CMD_CALL_PROPAGATE_REPL;
3461 }
3462 call(c,call_flags);
3463
3464 /* Convert the result of the Redis command into a module reply. */
3465 sds proto = sdsnewlen(c->buf,c->bufpos);
3466 c->bufpos = 0;
3467 while(listLength(c->reply)) {
3468 clientReplyBlock *o = listNodeValue(listFirst(c->reply));
3469
3470 proto = sdscatlen(proto,o->buf,o->used);
3471 listDelNode(c->reply,listFirst(c->reply));
3472 }
3473 reply = moduleCreateCallReplyFromProto(ctx,proto);
3474 autoMemoryAdd(ctx,REDISMODULE_AM_REPLY,reply);
3475
3476 cleanup:
3477 if (ctx->module) ctx->module->in_call--;
3478 freeClient(c);
3479 return reply;
3480 }
3481
3482 /* Return a pointer, and a length, to the protocol returned by the command
3483 * that returned the reply object. */
RM_CallReplyProto(RedisModuleCallReply * reply,size_t * len)3484 const char *RM_CallReplyProto(RedisModuleCallReply *reply, size_t *len) {
3485 if (reply->proto) *len = sdslen(reply->proto);
3486 return reply->proto;
3487 }
3488
3489 /* --------------------------------------------------------------------------
3490 * Modules data types
3491 *
3492 * When String DMA or using existing data structures is not enough, it is
3493 * possible to create new data types from scratch and export them to
3494 * Redis. The module must provide a set of callbacks for handling the
3495 * new values exported (for example in order to provide RDB saving/loading,
3496 * AOF rewrite, and so forth). In this section we define this API.
3497 * -------------------------------------------------------------------------- */
3498
3499 /* Turn a 9 chars name in the specified charset and a 10 bit encver into
3500 * a single 64 bit unsigned integer that represents this exact module name
3501 * and version. This final number is called a "type ID" and is used when
3502 * writing module exported values to RDB files, in order to re-associate the
3503 * value to the right module to load them during RDB loading.
3504 *
3505 * If the string is not of the right length or the charset is wrong, or
3506 * if encver is outside the unsigned 10 bit integer range, 0 is returned,
3507 * otherwise the function returns the right type ID.
3508 *
3509 * The resulting 64 bit integer is composed as follows:
3510 *
3511 * (high order bits) 6|6|6|6|6|6|6|6|6|10 (low order bits)
3512 *
3513 * The first 6 bits value is the first character, name[0], while the last
3514 * 6 bits value, immediately before the 10 bits integer, is name[8].
3515 * The last 10 bits are the encoding version.
3516 *
3517 * Note that a name and encver combo of "AAAAAAAAA" and 0, will produce
3518 * zero as return value, that is the same we use to signal errors, thus
3519 * this combination is invalid, and also useless since type names should
3520 * try to be vary to avoid collisions. */
3521
3522 const char *ModuleTypeNameCharSet =
3523 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
3524 "abcdefghijklmnopqrstuvwxyz"
3525 "0123456789-_";
3526
moduleTypeEncodeId(const char * name,int encver)3527 uint64_t moduleTypeEncodeId(const char *name, int encver) {
3528 /* We use 64 symbols so that we can map each character into 6 bits
3529 * of the final output. */
3530 const char *cset = ModuleTypeNameCharSet;
3531 if (strlen(name) != 9) return 0;
3532 if (encver < 0 || encver > 1023) return 0;
3533
3534 uint64_t id = 0;
3535 for (int j = 0; j < 9; j++) {
3536 char *p = strchr(cset,name[j]);
3537 if (!p) return 0;
3538 unsigned long pos = p-cset;
3539 id = (id << 6) | pos;
3540 }
3541 id = (id << 10) | encver;
3542 return id;
3543 }
3544
3545 /* Search, in the list of exported data types of all the modules registered,
3546 * a type with the same name as the one given. Returns the moduleType
3547 * structure pointer if such a module is found, or NULL otherwise. */
moduleTypeLookupModuleByName(const char * name)3548 moduleType *moduleTypeLookupModuleByName(const char *name) {
3549 dictIterator *di = dictGetIterator(modules);
3550 dictEntry *de;
3551
3552 while ((de = dictNext(di)) != NULL) {
3553 struct RedisModule *module = dictGetVal(de);
3554 listIter li;
3555 listNode *ln;
3556
3557 listRewind(module->types,&li);
3558 while((ln = listNext(&li))) {
3559 moduleType *mt = ln->value;
3560 if (memcmp(name,mt->name,sizeof(mt->name)) == 0) {
3561 dictReleaseIterator(di);
3562 return mt;
3563 }
3564 }
3565 }
3566 dictReleaseIterator(di);
3567 return NULL;
3568 }
3569
3570 /* Lookup a module by ID, with caching. This function is used during RDB
3571 * loading. Modules exporting data types should never be able to unload, so
3572 * our cache does not need to expire. */
3573 #define MODULE_LOOKUP_CACHE_SIZE 3
3574
moduleTypeLookupModuleByID(uint64_t id)3575 moduleType *moduleTypeLookupModuleByID(uint64_t id) {
3576 static struct {
3577 uint64_t id;
3578 moduleType *mt;
3579 } cache[MODULE_LOOKUP_CACHE_SIZE];
3580
3581 /* Search in cache to start. */
3582 int j;
3583 for (j = 0; j < MODULE_LOOKUP_CACHE_SIZE && cache[j].mt != NULL; j++)
3584 if (cache[j].id == id) return cache[j].mt;
3585
3586 /* Slow module by module lookup. */
3587 moduleType *mt = NULL;
3588 dictIterator *di = dictGetIterator(modules);
3589 dictEntry *de;
3590
3591 while ((de = dictNext(di)) != NULL && mt == NULL) {
3592 struct RedisModule *module = dictGetVal(de);
3593 listIter li;
3594 listNode *ln;
3595
3596 listRewind(module->types,&li);
3597 while((ln = listNext(&li))) {
3598 moduleType *this_mt = ln->value;
3599 /* Compare only the 54 bit module identifier and not the
3600 * encoding version. */
3601 if (this_mt->id >> 10 == id >> 10) {
3602 mt = this_mt;
3603 break;
3604 }
3605 }
3606 }
3607 dictReleaseIterator(di);
3608
3609 /* Add to cache if possible. */
3610 if (mt && j < MODULE_LOOKUP_CACHE_SIZE) {
3611 cache[j].id = id;
3612 cache[j].mt = mt;
3613 }
3614 return mt;
3615 }
3616
3617 /* Turn an (unresolved) module ID into a type name, to show the user an
3618 * error when RDB files contain module data we can't load.
3619 * The buffer pointed by 'name' must be 10 bytes at least. The function will
3620 * fill it with a null terminated module name. */
moduleTypeNameByID(char * name,uint64_t moduleid)3621 void moduleTypeNameByID(char *name, uint64_t moduleid) {
3622 const char *cset = ModuleTypeNameCharSet;
3623
3624 name[9] = '\0';
3625 char *p = name+8;
3626 moduleid >>= 10;
3627 for (int j = 0; j < 9; j++) {
3628 *p-- = cset[moduleid & 63];
3629 moduleid >>= 6;
3630 }
3631 }
3632
3633 /* Register a new data type exported by the module. The parameters are the
3634 * following. Please for in depth documentation check the modules API
3635 * documentation, especially https://redis.io/topics/modules-native-types.
3636 *
3637 * * **name**: A 9 characters data type name that MUST be unique in the Redis
3638 * Modules ecosystem. Be creative... and there will be no collisions. Use
3639 * the charset A-Z a-z 9-0, plus the two "-_" characters. A good
3640 * idea is to use, for example `<typename>-<vendor>`. For example
3641 * "tree-AntZ" may mean "Tree data structure by @antirez". To use both
3642 * lower case and upper case letters helps in order to prevent collisions.
3643 * * **encver**: Encoding version, which is, the version of the serialization
3644 * that a module used in order to persist data. As long as the "name"
3645 * matches, the RDB loading will be dispatched to the type callbacks
3646 * whatever 'encver' is used, however the module can understand if
3647 * the encoding it must load are of an older version of the module.
3648 * For example the module "tree-AntZ" initially used encver=0. Later
3649 * after an upgrade, it started to serialize data in a different format
3650 * and to register the type with encver=1. However this module may
3651 * still load old data produced by an older version if the rdb_load
3652 * callback is able to check the encver value and act accordingly.
3653 * The encver must be a positive value between 0 and 1023.
3654 * * **typemethods_ptr** is a pointer to a RedisModuleTypeMethods structure
3655 * that should be populated with the methods callbacks and structure
3656 * version, like in the following example:
3657 *
3658 * RedisModuleTypeMethods tm = {
3659 * .version = REDISMODULE_TYPE_METHOD_VERSION,
3660 * .rdb_load = myType_RDBLoadCallBack,
3661 * .rdb_save = myType_RDBSaveCallBack,
3662 * .aof_rewrite = myType_AOFRewriteCallBack,
3663 * .free = myType_FreeCallBack,
3664 *
3665 * // Optional fields
3666 * .digest = myType_DigestCallBack,
3667 * .mem_usage = myType_MemUsageCallBack,
3668 * .aux_load = myType_AuxRDBLoadCallBack,
3669 * .aux_save = myType_AuxRDBSaveCallBack,
3670 * }
3671 *
3672 * * **rdb_load**: A callback function pointer that loads data from RDB files.
3673 * * **rdb_save**: A callback function pointer that saves data to RDB files.
3674 * * **aof_rewrite**: A callback function pointer that rewrites data as commands.
3675 * * **digest**: A callback function pointer that is used for `DEBUG DIGEST`.
3676 * * **free**: A callback function pointer that can free a type value.
3677 * * **aux_save**: A callback function pointer that saves out of keyspace data to RDB files.
3678 * 'when' argument is either REDISMODULE_AUX_BEFORE_RDB or REDISMODULE_AUX_AFTER_RDB.
3679 * * **aux_load**: A callback function pointer that loads out of keyspace data from RDB files.
3680 * Similar to aux_save, returns REDISMODULE_OK on success, and ERR otherwise.
3681 *
3682 * The **digest** and **mem_usage** methods should currently be omitted since
3683 * they are not yet implemented inside the Redis modules core.
3684 *
3685 * Note: the module name "AAAAAAAAA" is reserved and produces an error, it
3686 * happens to be pretty lame as well.
3687 *
3688 * If there is already a module registering a type with the same name,
3689 * and if the module name or encver is invalid, NULL is returned.
3690 * Otherwise the new type is registered into Redis, and a reference of
3691 * type RedisModuleType is returned: the caller of the function should store
3692 * this reference into a global variable to make future use of it in the
3693 * modules type API, since a single module may register multiple types.
3694 * Example code fragment:
3695 *
3696 * static RedisModuleType *BalancedTreeType;
3697 *
3698 * int RedisModule_OnLoad(RedisModuleCtx *ctx) {
3699 * // some code here ...
3700 * BalancedTreeType = RM_CreateDataType(...);
3701 * }
3702 */
RM_CreateDataType(RedisModuleCtx * ctx,const char * name,int encver,void * typemethods_ptr)3703 moduleType *RM_CreateDataType(RedisModuleCtx *ctx, const char *name, int encver, void *typemethods_ptr) {
3704 uint64_t id = moduleTypeEncodeId(name,encver);
3705 if (id == 0) return NULL;
3706 if (moduleTypeLookupModuleByName(name) != NULL) return NULL;
3707
3708 long typemethods_version = ((long*)typemethods_ptr)[0];
3709 if (typemethods_version == 0) return NULL;
3710
3711 struct typemethods {
3712 uint64_t version;
3713 moduleTypeLoadFunc rdb_load;
3714 moduleTypeSaveFunc rdb_save;
3715 moduleTypeRewriteFunc aof_rewrite;
3716 moduleTypeMemUsageFunc mem_usage;
3717 moduleTypeDigestFunc digest;
3718 moduleTypeFreeFunc free;
3719 struct {
3720 moduleTypeAuxLoadFunc aux_load;
3721 moduleTypeAuxSaveFunc aux_save;
3722 int aux_save_triggers;
3723 } v2;
3724 } *tms = (struct typemethods*) typemethods_ptr;
3725
3726 moduleType *mt = zcalloc(sizeof(*mt));
3727 mt->id = id;
3728 mt->module = ctx->module;
3729 mt->rdb_load = tms->rdb_load;
3730 mt->rdb_save = tms->rdb_save;
3731 mt->aof_rewrite = tms->aof_rewrite;
3732 mt->mem_usage = tms->mem_usage;
3733 mt->digest = tms->digest;
3734 mt->free = tms->free;
3735 if (tms->version >= 2) {
3736 mt->aux_load = tms->v2.aux_load;
3737 mt->aux_save = tms->v2.aux_save;
3738 mt->aux_save_triggers = tms->v2.aux_save_triggers;
3739 }
3740 memcpy(mt->name,name,sizeof(mt->name));
3741 listAddNodeTail(ctx->module->types,mt);
3742 return mt;
3743 }
3744
3745 /* If the key is open for writing, set the specified module type object
3746 * as the value of the key, deleting the old value if any.
3747 * On success REDISMODULE_OK is returned. If the key is not open for
3748 * writing or there is an active iterator, REDISMODULE_ERR is returned. */
RM_ModuleTypeSetValue(RedisModuleKey * key,moduleType * mt,void * value)3749 int RM_ModuleTypeSetValue(RedisModuleKey *key, moduleType *mt, void *value) {
3750 if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR;
3751 RM_DeleteKey(key);
3752 robj *o = createModuleObject(mt,value);
3753 genericSetKey(key->ctx->client,key->db,key->key,o,0,0);
3754 decrRefCount(o);
3755 key->value = o;
3756 return REDISMODULE_OK;
3757 }
3758
3759 /* Assuming RedisModule_KeyType() returned REDISMODULE_KEYTYPE_MODULE on
3760 * the key, returns the module type pointer of the value stored at key.
3761 *
3762 * If the key is NULL, is not associated with a module type, or is empty,
3763 * then NULL is returned instead. */
RM_ModuleTypeGetType(RedisModuleKey * key)3764 moduleType *RM_ModuleTypeGetType(RedisModuleKey *key) {
3765 if (key == NULL ||
3766 key->value == NULL ||
3767 RM_KeyType(key) != REDISMODULE_KEYTYPE_MODULE) return NULL;
3768 moduleValue *mv = key->value->ptr;
3769 return mv->type;
3770 }
3771
3772 /* Assuming RedisModule_KeyType() returned REDISMODULE_KEYTYPE_MODULE on
3773 * the key, returns the module type low-level value stored at key, as
3774 * it was set by the user via RedisModule_ModuleTypeSetValue().
3775 *
3776 * If the key is NULL, is not associated with a module type, or is empty,
3777 * then NULL is returned instead. */
RM_ModuleTypeGetValue(RedisModuleKey * key)3778 void *RM_ModuleTypeGetValue(RedisModuleKey *key) {
3779 if (key == NULL ||
3780 key->value == NULL ||
3781 RM_KeyType(key) != REDISMODULE_KEYTYPE_MODULE) return NULL;
3782 moduleValue *mv = key->value->ptr;
3783 return mv->value;
3784 }
3785
3786 /* --------------------------------------------------------------------------
3787 * RDB loading and saving functions
3788 * -------------------------------------------------------------------------- */
3789
3790 /* Called when there is a load error in the context of a module. On some
3791 * modules this cannot be recovered, but if the module declared capability
3792 * to handle errors, we'll raise a flag rather than exiting. */
moduleRDBLoadError(RedisModuleIO * io)3793 void moduleRDBLoadError(RedisModuleIO *io) {
3794 if (io->type->module->options & REDISMODULE_OPTIONS_HANDLE_IO_ERRORS) {
3795 io->error = 1;
3796 return;
3797 }
3798 serverPanic(
3799 "Error loading data from RDB (short read or EOF). "
3800 "Read performed by module '%s' about type '%s' "
3801 "after reading '%llu' bytes of a value "
3802 "for key named: '%s'.",
3803 io->type->module->name,
3804 io->type->name,
3805 (unsigned long long)io->bytes,
3806 io->key? (char*)io->key->ptr: "(null)");
3807 }
3808
3809 /* Returns 0 if there's at least one registered data type that did not declare
3810 * REDISMODULE_OPTIONS_HANDLE_IO_ERRORS, in which case diskless loading should
3811 * be avoided since it could cause data loss. */
moduleAllDatatypesHandleErrors()3812 int moduleAllDatatypesHandleErrors() {
3813 dictIterator *di = dictGetIterator(modules);
3814 dictEntry *de;
3815
3816 while ((de = dictNext(di)) != NULL) {
3817 struct RedisModule *module = dictGetVal(de);
3818 if (listLength(module->types) &&
3819 !(module->options & REDISMODULE_OPTIONS_HANDLE_IO_ERRORS))
3820 {
3821 dictReleaseIterator(di);
3822 return 0;
3823 }
3824 }
3825 dictReleaseIterator(di);
3826 return 1;
3827 }
3828
3829 /* Returns true if any previous IO API failed.
3830 * for Load* APIs the REDISMODULE_OPTIONS_HANDLE_IO_ERRORS flag must be set with
3831 * RedisModule_SetModuleOptions first. */
RM_IsIOError(RedisModuleIO * io)3832 int RM_IsIOError(RedisModuleIO *io) {
3833 return io->error;
3834 }
3835
3836 /* Save an unsigned 64 bit value into the RDB file. This function should only
3837 * be called in the context of the rdb_save method of modules implementing new
3838 * data types. */
RM_SaveUnsigned(RedisModuleIO * io,uint64_t value)3839 void RM_SaveUnsigned(RedisModuleIO *io, uint64_t value) {
3840 if (io->error) return;
3841 /* Save opcode. */
3842 int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_UINT);
3843 if (retval == -1) goto saveerr;
3844 io->bytes += retval;
3845 /* Save value. */
3846 retval = rdbSaveLen(io->rio, value);
3847 if (retval == -1) goto saveerr;
3848 io->bytes += retval;
3849 return;
3850
3851 saveerr:
3852 io->error = 1;
3853 }
3854
3855 /* Load an unsigned 64 bit value from the RDB file. This function should only
3856 * be called in the context of the rdb_load method of modules implementing
3857 * new data types. */
RM_LoadUnsigned(RedisModuleIO * io)3858 uint64_t RM_LoadUnsigned(RedisModuleIO *io) {
3859 if (io->error) return 0;
3860 if (io->ver == 2) {
3861 uint64_t opcode = rdbLoadLen(io->rio,NULL);
3862 if (opcode != RDB_MODULE_OPCODE_UINT) goto loaderr;
3863 }
3864 uint64_t value;
3865 int retval = rdbLoadLenByRef(io->rio, NULL, &value);
3866 if (retval == -1) goto loaderr;
3867 return value;
3868
3869 loaderr:
3870 moduleRDBLoadError(io);
3871 return 0;
3872 }
3873
3874 /* Like RedisModule_SaveUnsigned() but for signed 64 bit values. */
RM_SaveSigned(RedisModuleIO * io,int64_t value)3875 void RM_SaveSigned(RedisModuleIO *io, int64_t value) {
3876 union {uint64_t u; int64_t i;} conv;
3877 conv.i = value;
3878 RM_SaveUnsigned(io,conv.u);
3879 }
3880
3881 /* Like RedisModule_LoadUnsigned() but for signed 64 bit values. */
RM_LoadSigned(RedisModuleIO * io)3882 int64_t RM_LoadSigned(RedisModuleIO *io) {
3883 union {uint64_t u; int64_t i;} conv;
3884 conv.u = RM_LoadUnsigned(io);
3885 return conv.i;
3886 }
3887
3888 /* In the context of the rdb_save method of a module type, saves a
3889 * string into the RDB file taking as input a RedisModuleString.
3890 *
3891 * The string can be later loaded with RedisModule_LoadString() or
3892 * other Load family functions expecting a serialized string inside
3893 * the RDB file. */
RM_SaveString(RedisModuleIO * io,RedisModuleString * s)3894 void RM_SaveString(RedisModuleIO *io, RedisModuleString *s) {
3895 if (io->error) return;
3896 /* Save opcode. */
3897 ssize_t retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING);
3898 if (retval == -1) goto saveerr;
3899 io->bytes += retval;
3900 /* Save value. */
3901 retval = rdbSaveStringObject(io->rio, s);
3902 if (retval == -1) goto saveerr;
3903 io->bytes += retval;
3904 return;
3905
3906 saveerr:
3907 io->error = 1;
3908 }
3909
3910 /* Like RedisModule_SaveString() but takes a raw C pointer and length
3911 * as input. */
RM_SaveStringBuffer(RedisModuleIO * io,const char * str,size_t len)3912 void RM_SaveStringBuffer(RedisModuleIO *io, const char *str, size_t len) {
3913 if (io->error) return;
3914 /* Save opcode. */
3915 ssize_t retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING);
3916 if (retval == -1) goto saveerr;
3917 io->bytes += retval;
3918 /* Save value. */
3919 retval = rdbSaveRawString(io->rio, (unsigned char*)str,len);
3920 if (retval == -1) goto saveerr;
3921 io->bytes += retval;
3922 return;
3923
3924 saveerr:
3925 io->error = 1;
3926 }
3927
3928 /* Implements RM_LoadString() and RM_LoadStringBuffer() */
moduleLoadString(RedisModuleIO * io,int plain,size_t * lenptr)3929 void *moduleLoadString(RedisModuleIO *io, int plain, size_t *lenptr) {
3930 if (io->error) return NULL;
3931 if (io->ver == 2) {
3932 uint64_t opcode = rdbLoadLen(io->rio,NULL);
3933 if (opcode != RDB_MODULE_OPCODE_STRING) goto loaderr;
3934 }
3935 void *s = rdbGenericLoadStringObject(io->rio,
3936 plain ? RDB_LOAD_PLAIN : RDB_LOAD_NONE, lenptr);
3937 if (s == NULL) goto loaderr;
3938 return s;
3939
3940 loaderr:
3941 moduleRDBLoadError(io);
3942 return NULL;
3943 }
3944
3945 /* In the context of the rdb_load method of a module data type, loads a string
3946 * from the RDB file, that was previously saved with RedisModule_SaveString()
3947 * functions family.
3948 *
3949 * The returned string is a newly allocated RedisModuleString object, and
3950 * the user should at some point free it with a call to RedisModule_FreeString().
3951 *
3952 * If the data structure does not store strings as RedisModuleString objects,
3953 * the similar function RedisModule_LoadStringBuffer() could be used instead. */
RM_LoadString(RedisModuleIO * io)3954 RedisModuleString *RM_LoadString(RedisModuleIO *io) {
3955 return moduleLoadString(io,0,NULL);
3956 }
3957
3958 /* Like RedisModule_LoadString() but returns an heap allocated string that
3959 * was allocated with RedisModule_Alloc(), and can be resized or freed with
3960 * RedisModule_Realloc() or RedisModule_Free().
3961 *
3962 * The size of the string is stored at '*lenptr' if not NULL.
3963 * The returned string is not automatically NULL terminated, it is loaded
3964 * exactly as it was stored inside the RDB file. */
RM_LoadStringBuffer(RedisModuleIO * io,size_t * lenptr)3965 char *RM_LoadStringBuffer(RedisModuleIO *io, size_t *lenptr) {
3966 return moduleLoadString(io,1,lenptr);
3967 }
3968
3969 /* In the context of the rdb_save method of a module data type, saves a double
3970 * value to the RDB file. The double can be a valid number, a NaN or infinity.
3971 * It is possible to load back the value with RedisModule_LoadDouble(). */
RM_SaveDouble(RedisModuleIO * io,double value)3972 void RM_SaveDouble(RedisModuleIO *io, double value) {
3973 if (io->error) return;
3974 /* Save opcode. */
3975 int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_DOUBLE);
3976 if (retval == -1) goto saveerr;
3977 io->bytes += retval;
3978 /* Save value. */
3979 retval = rdbSaveBinaryDoubleValue(io->rio, value);
3980 if (retval == -1) goto saveerr;
3981 io->bytes += retval;
3982 return;
3983
3984 saveerr:
3985 io->error = 1;
3986 }
3987
3988 /* In the context of the rdb_save method of a module data type, loads back the
3989 * double value saved by RedisModule_SaveDouble(). */
RM_LoadDouble(RedisModuleIO * io)3990 double RM_LoadDouble(RedisModuleIO *io) {
3991 if (io->error) return 0;
3992 if (io->ver == 2) {
3993 uint64_t opcode = rdbLoadLen(io->rio,NULL);
3994 if (opcode != RDB_MODULE_OPCODE_DOUBLE) goto loaderr;
3995 }
3996 double value;
3997 int retval = rdbLoadBinaryDoubleValue(io->rio, &value);
3998 if (retval == -1) goto loaderr;
3999 return value;
4000
4001 loaderr:
4002 moduleRDBLoadError(io);
4003 return 0;
4004 }
4005
4006 /* In the context of the rdb_save method of a module data type, saves a float
4007 * value to the RDB file. The float can be a valid number, a NaN or infinity.
4008 * It is possible to load back the value with RedisModule_LoadFloat(). */
RM_SaveFloat(RedisModuleIO * io,float value)4009 void RM_SaveFloat(RedisModuleIO *io, float value) {
4010 if (io->error) return;
4011 /* Save opcode. */
4012 int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_FLOAT);
4013 if (retval == -1) goto saveerr;
4014 io->bytes += retval;
4015 /* Save value. */
4016 retval = rdbSaveBinaryFloatValue(io->rio, value);
4017 if (retval == -1) goto saveerr;
4018 io->bytes += retval;
4019 return;
4020
4021 saveerr:
4022 io->error = 1;
4023 }
4024
4025 /* In the context of the rdb_save method of a module data type, loads back the
4026 * float value saved by RedisModule_SaveFloat(). */
RM_LoadFloat(RedisModuleIO * io)4027 float RM_LoadFloat(RedisModuleIO *io) {
4028 if (io->error) return 0;
4029 if (io->ver == 2) {
4030 uint64_t opcode = rdbLoadLen(io->rio,NULL);
4031 if (opcode != RDB_MODULE_OPCODE_FLOAT) goto loaderr;
4032 }
4033 float value;
4034 int retval = rdbLoadBinaryFloatValue(io->rio, &value);
4035 if (retval == -1) goto loaderr;
4036 return value;
4037
4038 loaderr:
4039 moduleRDBLoadError(io);
4040 return 0;
4041 }
4042
4043 /* In the context of the rdb_save method of a module data type, saves a long double
4044 * value to the RDB file. The double can be a valid number, a NaN or infinity.
4045 * It is possible to load back the value with RedisModule_LoadLongDouble(). */
RM_SaveLongDouble(RedisModuleIO * io,long double value)4046 void RM_SaveLongDouble(RedisModuleIO *io, long double value) {
4047 if (io->error) return;
4048 char buf[MAX_LONG_DOUBLE_CHARS];
4049 /* Long double has different number of bits in different platforms, so we
4050 * save it as a string type. */
4051 size_t len = ld2string(buf,sizeof(buf),value,LD_STR_HEX);
4052 RM_SaveStringBuffer(io,buf,len);
4053 }
4054
4055 /* In the context of the rdb_save method of a module data type, loads back the
4056 * long double value saved by RedisModule_SaveLongDouble(). */
RM_LoadLongDouble(RedisModuleIO * io)4057 long double RM_LoadLongDouble(RedisModuleIO *io) {
4058 if (io->error) return 0;
4059 long double value;
4060 size_t len;
4061 char* str = RM_LoadStringBuffer(io,&len);
4062 if (!str) return 0;
4063 string2ld(str,len,&value);
4064 RM_Free(str);
4065 return value;
4066 }
4067
4068 /* Iterate over modules, and trigger rdb aux saving for the ones modules types
4069 * who asked for it. */
rdbSaveModulesAux(rio * rdb,int when)4070 ssize_t rdbSaveModulesAux(rio *rdb, int when) {
4071 size_t total_written = 0;
4072 dictIterator *di = dictGetIterator(modules);
4073 dictEntry *de;
4074
4075 while ((de = dictNext(di)) != NULL) {
4076 struct RedisModule *module = dictGetVal(de);
4077 listIter li;
4078 listNode *ln;
4079
4080 listRewind(module->types,&li);
4081 while((ln = listNext(&li))) {
4082 moduleType *mt = ln->value;
4083 if (!mt->aux_save || !(mt->aux_save_triggers & when))
4084 continue;
4085 ssize_t ret = rdbSaveSingleModuleAux(rdb, when, mt);
4086 if (ret==-1) {
4087 dictReleaseIterator(di);
4088 return -1;
4089 }
4090 total_written += ret;
4091 }
4092 }
4093
4094 dictReleaseIterator(di);
4095 return total_written;
4096 }
4097
4098 /* --------------------------------------------------------------------------
4099 * Key digest API (DEBUG DIGEST interface for modules types)
4100 * -------------------------------------------------------------------------- */
4101
4102 /* Add a new element to the digest. This function can be called multiple times
4103 * one element after the other, for all the elements that constitute a given
4104 * data structure. The function call must be followed by the call to
4105 * `RedisModule_DigestEndSequence` eventually, when all the elements that are
4106 * always in a given order are added. See the Redis Modules data types
4107 * documentation for more info. However this is a quick example that uses Redis
4108 * data types as an example.
4109 *
4110 * To add a sequence of unordered elements (for example in the case of a Redis
4111 * Set), the pattern to use is:
4112 *
4113 * foreach element {
4114 * AddElement(element);
4115 * EndSequence();
4116 * }
4117 *
4118 * Because Sets are not ordered, so every element added has a position that
4119 * does not depend from the other. However if instead our elements are
4120 * ordered in pairs, like field-value pairs of an Hash, then one should
4121 * use:
4122 *
4123 * foreach key,value {
4124 * AddElement(key);
4125 * AddElement(value);
4126 * EndSquence();
4127 * }
4128 *
4129 * Because the key and value will be always in the above order, while instead
4130 * the single key-value pairs, can appear in any position into a Redis hash.
4131 *
4132 * A list of ordered elements would be implemented with:
4133 *
4134 * foreach element {
4135 * AddElement(element);
4136 * }
4137 * EndSequence();
4138 *
4139 */
RM_DigestAddStringBuffer(RedisModuleDigest * md,unsigned char * ele,size_t len)4140 void RM_DigestAddStringBuffer(RedisModuleDigest *md, unsigned char *ele, size_t len) {
4141 mixDigest(md->o,ele,len);
4142 }
4143
4144 /* Like `RedisModule_DigestAddStringBuffer()` but takes a long long as input
4145 * that gets converted into a string before adding it to the digest. */
RM_DigestAddLongLong(RedisModuleDigest * md,long long ll)4146 void RM_DigestAddLongLong(RedisModuleDigest *md, long long ll) {
4147 char buf[LONG_STR_SIZE];
4148 size_t len = ll2string(buf,sizeof(buf),ll);
4149 mixDigest(md->o,buf,len);
4150 }
4151
4152 /* See the documentation for `RedisModule_DigestAddElement()`. */
RM_DigestEndSequence(RedisModuleDigest * md)4153 void RM_DigestEndSequence(RedisModuleDigest *md) {
4154 xorDigest(md->x,md->o,sizeof(md->o));
4155 memset(md->o,0,sizeof(md->o));
4156 }
4157
4158 /* Decode a serialized representation of a module data type 'mt' from string
4159 * 'str' and return a newly allocated value, or NULL if decoding failed.
4160 *
4161 * This call basically reuses the 'rdb_load' callback which module data types
4162 * implement in order to allow a module to arbitrarily serialize/de-serialize
4163 * keys, similar to how the Redis 'DUMP' and 'RESTORE' commands are implemented.
4164 *
4165 * Modules should generally use the REDISMODULE_OPTIONS_HANDLE_IO_ERRORS flag and
4166 * make sure the de-serialization code properly checks and handles IO errors
4167 * (freeing allocated buffers and returning a NULL).
4168 *
4169 * If this is NOT done, Redis will handle corrupted (or just truncated) serialized
4170 * data by producing an error message and terminating the process.
4171 */
4172
RM_LoadDataTypeFromString(const RedisModuleString * str,const moduleType * mt)4173 void *RM_LoadDataTypeFromString(const RedisModuleString *str, const moduleType *mt) {
4174 rio payload;
4175 RedisModuleIO io;
4176 void *ret;
4177
4178 rioInitWithBuffer(&payload, str->ptr);
4179 moduleInitIOContext(io,(moduleType *)mt,&payload,NULL);
4180
4181 /* All RM_Save*() calls always write a version 2 compatible format, so we
4182 * need to make sure we read the same.
4183 */
4184 io.ver = 2;
4185 ret = mt->rdb_load(&io,0);
4186 if (io.ctx) {
4187 moduleFreeContext(io.ctx);
4188 zfree(io.ctx);
4189 }
4190 return ret;
4191 }
4192
4193 /* Encode a module data type 'mt' value 'data' into serialized form, and return it
4194 * as a newly allocated RedisModuleString.
4195 *
4196 * This call basically reuses the 'rdb_save' callback which module data types
4197 * implement in order to allow a module to arbitrarily serialize/de-serialize
4198 * keys, similar to how the Redis 'DUMP' and 'RESTORE' commands are implemented.
4199 */
4200
RM_SaveDataTypeToString(RedisModuleCtx * ctx,void * data,const moduleType * mt)4201 RedisModuleString *RM_SaveDataTypeToString(RedisModuleCtx *ctx, void *data, const moduleType *mt) {
4202 rio payload;
4203 RedisModuleIO io;
4204
4205 rioInitWithBuffer(&payload,sdsempty());
4206 moduleInitIOContext(io,(moduleType *)mt,&payload,NULL);
4207 mt->rdb_save(&io,data);
4208 if (io.ctx) {
4209 moduleFreeContext(io.ctx);
4210 zfree(io.ctx);
4211 }
4212 if (io.error) {
4213 return NULL;
4214 } else {
4215 robj *str = createObject(OBJ_STRING,payload.io.buffer.ptr);
4216 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,str);
4217 return str;
4218 }
4219 }
4220
4221 /* --------------------------------------------------------------------------
4222 * AOF API for modules data types
4223 * -------------------------------------------------------------------------- */
4224
4225 /* Emits a command into the AOF during the AOF rewriting process. This function
4226 * is only called in the context of the aof_rewrite method of data types exported
4227 * by a module. The command works exactly like RedisModule_Call() in the way
4228 * the parameters are passed, but it does not return anything as the error
4229 * handling is performed by Redis itself. */
RM_EmitAOF(RedisModuleIO * io,const char * cmdname,const char * fmt,...)4230 void RM_EmitAOF(RedisModuleIO *io, const char *cmdname, const char *fmt, ...) {
4231 if (io->error) return;
4232 struct redisCommand *cmd;
4233 robj **argv = NULL;
4234 int argc = 0, flags = 0, j;
4235 va_list ap;
4236
4237 cmd = lookupCommandByCString((char*)cmdname);
4238 if (!cmd) {
4239 serverLog(LL_WARNING,
4240 "Fatal: AOF method for module data type '%s' tried to "
4241 "emit unknown command '%s'",
4242 io->type->name, cmdname);
4243 io->error = 1;
4244 errno = EINVAL;
4245 return;
4246 }
4247
4248 /* Emit the arguments into the AOF in Redis protocol format. */
4249 va_start(ap, fmt);
4250 argv = moduleCreateArgvFromUserFormat(cmdname,fmt,&argc,&flags,ap);
4251 va_end(ap);
4252 if (argv == NULL) {
4253 serverLog(LL_WARNING,
4254 "Fatal: AOF method for module data type '%s' tried to "
4255 "call RedisModule_EmitAOF() with wrong format specifiers '%s'",
4256 io->type->name, fmt);
4257 io->error = 1;
4258 errno = EINVAL;
4259 return;
4260 }
4261
4262 /* Bulk count. */
4263 if (!io->error && rioWriteBulkCount(io->rio,'*',argc) == 0)
4264 io->error = 1;
4265
4266 /* Arguments. */
4267 for (j = 0; j < argc; j++) {
4268 if (!io->error && rioWriteBulkObject(io->rio,argv[j]) == 0)
4269 io->error = 1;
4270 decrRefCount(argv[j]);
4271 }
4272 zfree(argv);
4273 return;
4274 }
4275
4276 /* --------------------------------------------------------------------------
4277 * IO context handling
4278 * -------------------------------------------------------------------------- */
4279
RM_GetContextFromIO(RedisModuleIO * io)4280 RedisModuleCtx *RM_GetContextFromIO(RedisModuleIO *io) {
4281 if (io->ctx) return io->ctx; /* Can't have more than one... */
4282 RedisModuleCtx ctxtemplate = REDISMODULE_CTX_INIT;
4283 io->ctx = zmalloc(sizeof(RedisModuleCtx));
4284 *(io->ctx) = ctxtemplate;
4285 io->ctx->module = io->type->module;
4286 io->ctx->client = NULL;
4287 return io->ctx;
4288 }
4289
4290 /* Returns a RedisModuleString with the name of the key currently saving or
4291 * loading, when an IO data type callback is called. There is no guarantee
4292 * that the key name is always available, so this may return NULL.
4293 */
RM_GetKeyNameFromIO(RedisModuleIO * io)4294 const RedisModuleString *RM_GetKeyNameFromIO(RedisModuleIO *io) {
4295 return io->key;
4296 }
4297
4298 /* Returns a RedisModuleString with the name of the key from RedisModuleKey */
RM_GetKeyNameFromModuleKey(RedisModuleKey * key)4299 const RedisModuleString *RM_GetKeyNameFromModuleKey(RedisModuleKey *key) {
4300 return key ? key->key : NULL;
4301 }
4302
4303 /* --------------------------------------------------------------------------
4304 * Logging
4305 * -------------------------------------------------------------------------- */
4306
4307 /* This is the low level function implementing both:
4308 *
4309 * RM_Log()
4310 * RM_LogIOError()
4311 *
4312 */
RM_LogRaw(RedisModule * module,const char * levelstr,const char * fmt,va_list ap)4313 void RM_LogRaw(RedisModule *module, const char *levelstr, const char *fmt, va_list ap) {
4314 char msg[LOG_MAX_LEN];
4315 size_t name_len;
4316 int level;
4317
4318 if (!strcasecmp(levelstr,"debug")) level = LL_DEBUG;
4319 else if (!strcasecmp(levelstr,"verbose")) level = LL_VERBOSE;
4320 else if (!strcasecmp(levelstr,"notice")) level = LL_NOTICE;
4321 else if (!strcasecmp(levelstr,"warning")) level = LL_WARNING;
4322 else level = LL_VERBOSE; /* Default. */
4323
4324 if (level < server.verbosity) return;
4325
4326 name_len = snprintf(msg, sizeof(msg),"<%s> ", module? module->name: "module");
4327 vsnprintf(msg + name_len, sizeof(msg) - name_len, fmt, ap);
4328 serverLogRaw(level,msg);
4329 }
4330
4331 /* Produces a log message to the standard Redis log, the format accepts
4332 * printf-alike specifiers, while level is a string describing the log
4333 * level to use when emitting the log, and must be one of the following:
4334 *
4335 * * "debug"
4336 * * "verbose"
4337 * * "notice"
4338 * * "warning"
4339 *
4340 * If the specified log level is invalid, verbose is used by default.
4341 * There is a fixed limit to the length of the log line this function is able
4342 * to emit, this limit is not specified but is guaranteed to be more than
4343 * a few lines of text.
4344 *
4345 * The ctx argument may be NULL if cannot be provided in the context of the
4346 * caller for instance threads or callbacks, in which case a generic "module"
4347 * will be used instead of the module name.
4348 */
RM_Log(RedisModuleCtx * ctx,const char * levelstr,const char * fmt,...)4349 void RM_Log(RedisModuleCtx *ctx, const char *levelstr, const char *fmt, ...) {
4350 va_list ap;
4351 va_start(ap, fmt);
4352 RM_LogRaw(ctx? ctx->module: NULL,levelstr,fmt,ap);
4353 va_end(ap);
4354 }
4355
4356 /* Log errors from RDB / AOF serialization callbacks.
4357 *
4358 * This function should be used when a callback is returning a critical
4359 * error to the caller since cannot load or save the data for some
4360 * critical reason. */
RM_LogIOError(RedisModuleIO * io,const char * levelstr,const char * fmt,...)4361 void RM_LogIOError(RedisModuleIO *io, const char *levelstr, const char *fmt, ...) {
4362 va_list ap;
4363 va_start(ap, fmt);
4364 RM_LogRaw(io->type->module,levelstr,fmt,ap);
4365 va_end(ap);
4366 }
4367
4368 /* Redis-like assert function.
4369 *
4370 * A failed assertion will shut down the server and produce logging information
4371 * that looks identical to information generated by Redis itself.
4372 */
RM__Assert(const char * estr,const char * file,int line)4373 void RM__Assert(const char *estr, const char *file, int line) {
4374 _serverAssert(estr, file, line);
4375 }
4376
4377 /* Allows adding event to the latency monitor to be observed by the LATENCY
4378 * command. The call is skipped if the latency is smaller than the configured
4379 * latency-monitor-threshold. */
RM_LatencyAddSample(const char * event,mstime_t latency)4380 void RM_LatencyAddSample(const char *event, mstime_t latency) {
4381 if (latency >= server.latency_monitor_threshold)
4382 latencyAddSample(event, latency);
4383 }
4384
4385 /* --------------------------------------------------------------------------
4386 * Blocking clients from modules
4387 * -------------------------------------------------------------------------- */
4388
4389 /* Readable handler for the awake pipe. We do nothing here, the awake bytes
4390 * will be actually read in a more appropriate place in the
4391 * moduleHandleBlockedClients() function that is where clients are actually
4392 * served. */
moduleBlockedClientPipeReadable(aeEventLoop * el,int fd,void * privdata,int mask)4393 void moduleBlockedClientPipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) {
4394 UNUSED(el);
4395 UNUSED(fd);
4396 UNUSED(mask);
4397 UNUSED(privdata);
4398 }
4399
4400 /* This is called from blocked.c in order to unblock a client: may be called
4401 * for multiple reasons while the client is in the middle of being blocked
4402 * because the client is terminated, but is also called for cleanup when a
4403 * client is unblocked in a clean way after replaying.
4404 *
4405 * What we do here is just to set the client to NULL in the redis module
4406 * blocked client handle. This way if the client is terminated while there
4407 * is a pending threaded operation involving the blocked client, we'll know
4408 * that the client no longer exists and no reply callback should be called.
4409 *
4410 * The structure RedisModuleBlockedClient will be always deallocated when
4411 * running the list of clients blocked by a module that need to be unblocked. */
unblockClientFromModule(client * c)4412 void unblockClientFromModule(client *c) {
4413 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
4414
4415 /* Call the disconnection callback if any. Note that
4416 * bc->disconnect_callback is set to NULL if the client gets disconnected
4417 * by the module itself or because of a timeout, so the callback will NOT
4418 * get called if this is not an actual disconnection event. */
4419 if (bc->disconnect_callback) {
4420 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
4421 ctx.blocked_privdata = bc->privdata;
4422 ctx.module = bc->module;
4423 ctx.client = bc->client;
4424 bc->disconnect_callback(&ctx,bc);
4425 moduleFreeContext(&ctx);
4426 }
4427
4428 /* If we made it here and client is still blocked it means that the command
4429 * timed-out, client was killed or disconnected and disconnect_callback was
4430 * not implemented (or it was, but RM_UnblockClient was not called from
4431 * within it, as it should).
4432 * We must call moduleUnblockClient in order to free privdata and
4433 * RedisModuleBlockedClient.
4434 *
4435 * Note that we only do that for clients that are blocked on keys, for which
4436 * the contract is that the module should not call RM_UnblockClient under
4437 * normal circumstances.
4438 * Clients implementing threads and working with private data should be
4439 * aware that calling RM_UnblockClient for every blocked client is their
4440 * responsibility, and if they fail to do so memory may leak. Ideally they
4441 * should implement the disconnect and timeout callbacks and call
4442 * RM_UnblockClient, but any other way is also acceptable. */
4443 if (bc->blocked_on_keys && !bc->unblocked)
4444 moduleUnblockClient(c);
4445
4446 bc->client = NULL;
4447 /* Reset the client for a new query since, for blocking commands implemented
4448 * into modules, we do not it immediately after the command returns (and
4449 * the client blocks) in order to be still able to access the argument
4450 * vector from callbacks. */
4451 resetClient(c);
4452 }
4453
4454 /* Block a client in the context of a module: this function implements both
4455 * RM_BlockClient() and RM_BlockClientOnKeys() depending on the fact the
4456 * keys are passed or not.
4457 *
4458 * When not blocking for keys, the keys, numkeys, and privdata parameters are
4459 * not needed. The privdata in that case must be NULL, since later is
4460 * RM_UnblockClient() that will provide some private data that the reply
4461 * callback will receive.
4462 *
4463 * Instead when blocking for keys, normally RM_UnblockClient() will not be
4464 * called (because the client will unblock when the key is modified), so
4465 * 'privdata' should be provided in that case, so that once the client is
4466 * unlocked and the reply callback is called, it will receive its associated
4467 * private data.
4468 *
4469 * Even when blocking on keys, RM_UnblockClient() can be called however, but
4470 * in that case the privdata argument is disregarded, because we pass the
4471 * reply callback the privdata that is set here while blocking.
4472 *
4473 */
moduleBlockClient(RedisModuleCtx * ctx,RedisModuleCmdFunc reply_callback,RedisModuleCmdFunc timeout_callback,void (* free_privdata)(RedisModuleCtx *,void *),long long timeout_ms,RedisModuleString ** keys,int numkeys,void * privdata)4474 RedisModuleBlockedClient *moduleBlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms, RedisModuleString **keys, int numkeys, void *privdata) {
4475 client *c = ctx->client;
4476 int islua = c->flags & CLIENT_LUA;
4477 int ismulti = c->flags & CLIENT_MULTI;
4478
4479 c->bpop.module_blocked_handle = zmalloc(sizeof(RedisModuleBlockedClient));
4480 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
4481 ctx->module->blocked_clients++;
4482
4483 /* We need to handle the invalid operation of calling modules blocking
4484 * commands from Lua or MULTI. We actually create an already aborted
4485 * (client set to NULL) blocked client handle, and actually reply with
4486 * an error. */
4487 mstime_t timeout = timeout_ms ? (mstime()+timeout_ms) : 0;
4488 bc->client = (islua || ismulti) ? NULL : c;
4489 bc->module = ctx->module;
4490 bc->reply_callback = reply_callback;
4491 bc->timeout_callback = timeout_callback;
4492 bc->disconnect_callback = NULL; /* Set by RM_SetDisconnectCallback() */
4493 bc->free_privdata = free_privdata;
4494 bc->privdata = privdata;
4495 bc->reply_client = createClient(NULL);
4496 bc->reply_client->flags |= CLIENT_MODULE;
4497 bc->dbid = c->db->id;
4498 bc->blocked_on_keys = keys != NULL;
4499 bc->unblocked = 0;
4500 c->bpop.timeout = timeout;
4501
4502 if (islua || ismulti) {
4503 c->bpop.module_blocked_handle = NULL;
4504 addReplyError(c, islua ?
4505 "Blocking module command called from Lua script" :
4506 "Blocking module command called from transaction");
4507 } else {
4508 if (keys) {
4509 blockForKeys(c,BLOCKED_MODULE,keys,numkeys,timeout,NULL,NULL);
4510 } else {
4511 blockClient(c,BLOCKED_MODULE);
4512 }
4513 }
4514 return bc;
4515 }
4516
4517 /* This function is called from module.c in order to check if a module
4518 * blocked for BLOCKED_MODULE and subtype 'on keys' (bc->blocked_on_keys true)
4519 * can really be unblocked, since the module was able to serve the client.
4520 * If the callback returns REDISMODULE_OK, then the client can be unblocked,
4521 * otherwise the client remains blocked and we'll retry again when one of
4522 * the keys it blocked for becomes "ready" again.
4523 * This function returns 1 if client was served (and should be unblocked) */
moduleTryServeClientBlockedOnKey(client * c,robj * key)4524 int moduleTryServeClientBlockedOnKey(client *c, robj *key) {
4525 int served = 0;
4526 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
4527
4528 /* Protect against re-processing: don't serve clients that are already
4529 * in the unblocking list for any reason (including RM_UnblockClient()
4530 * explicit call). See #6798. */
4531 if (bc->unblocked) return 0;
4532
4533 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
4534 ctx.flags |= REDISMODULE_CTX_BLOCKED_REPLY;
4535 ctx.blocked_ready_key = key;
4536 ctx.blocked_privdata = bc->privdata;
4537 ctx.module = bc->module;
4538 ctx.client = bc->client;
4539 ctx.blocked_client = bc;
4540 if (bc->reply_callback(&ctx,(void**)c->argv,c->argc) == REDISMODULE_OK)
4541 served = 1;
4542 moduleFreeContext(&ctx);
4543 return served;
4544 }
4545
4546 /* Block a client in the context of a blocking command, returning an handle
4547 * which will be used, later, in order to unblock the client with a call to
4548 * RedisModule_UnblockClient(). The arguments specify callback functions
4549 * and a timeout after which the client is unblocked.
4550 *
4551 * The callbacks are called in the following contexts:
4552 *
4553 * reply_callback: called after a successful RedisModule_UnblockClient()
4554 * call in order to reply to the client and unblock it.
4555 *
4556 * timeout_callback: called when the timeout is reached in order to send an
4557 * error to the client.
4558 *
4559 * free_privdata: called in order to free the private data that is passed
4560 * by RedisModule_UnblockClient() call.
4561 *
4562 * Note: RedisModule_UnblockClient should be called for every blocked client,
4563 * even if client was killed, timed-out or disconnected. Failing to do so
4564 * will result in memory leaks.
4565 *
4566 * There are some cases where RedisModule_BlockClient() cannot be used:
4567 *
4568 * 1. If the client is a Lua script.
4569 * 2. If the client is executing a MULTI block.
4570 *
4571 * In these cases, a call to RedisModule_BlockClient() will **not** block the
4572 * client, but instead produce a specific error reply.
4573 */
RM_BlockClient(RedisModuleCtx * ctx,RedisModuleCmdFunc reply_callback,RedisModuleCmdFunc timeout_callback,void (* free_privdata)(RedisModuleCtx *,void *),long long timeout_ms)4574 RedisModuleBlockedClient *RM_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms) {
4575 return moduleBlockClient(ctx,reply_callback,timeout_callback,free_privdata,timeout_ms, NULL,0,NULL);
4576 }
4577
4578 /* This call is similar to RedisModule_BlockClient(), however in this case we
4579 * don't just block the client, but also ask Redis to unblock it automatically
4580 * once certain keys become "ready", that is, contain more data.
4581 *
4582 * Basically this is similar to what a typical Redis command usually does,
4583 * like BLPOP or BZPOPMAX: the client blocks if it cannot be served ASAP,
4584 * and later when the key receives new data (a list push for instance), the
4585 * client is unblocked and served.
4586 *
4587 * However in the case of this module API, when the client is unblocked?
4588 *
4589 * 1. If you block on a key of a type that has blocking operations associated,
4590 * like a list, a sorted set, a stream, and so forth, the client may be
4591 * unblocked once the relevant key is targeted by an operation that normally
4592 * unblocks the native blocking operations for that type. So if we block
4593 * on a list key, an RPUSH command may unblock our client and so forth.
4594 * 2. If you are implementing your native data type, or if you want to add new
4595 * unblocking conditions in addition to "1", you can call the modules API
4596 * RedisModule_SignalKeyAsReady().
4597 *
4598 * Anyway we can't be sure if the client should be unblocked just because the
4599 * key is signaled as ready: for instance a successive operation may change the
4600 * key, or a client in queue before this one can be served, modifying the key
4601 * as well and making it empty again. So when a client is blocked with
4602 * RedisModule_BlockClientOnKeys() the reply callback is not called after
4603 * RM_UnblockCLient() is called, but every time a key is signaled as ready:
4604 * if the reply callback can serve the client, it returns REDISMODULE_OK
4605 * and the client is unblocked, otherwise it will return REDISMODULE_ERR
4606 * and we'll try again later.
4607 *
4608 * The reply callback can access the key that was signaled as ready by
4609 * calling the API RedisModule_GetBlockedClientReadyKey(), that returns
4610 * just the string name of the key as a RedisModuleString object.
4611 *
4612 * Thanks to this system we can setup complex blocking scenarios, like
4613 * unblocking a client only if a list contains at least 5 items or other
4614 * more fancy logics.
4615 *
4616 * Note that another difference with RedisModule_BlockClient(), is that here
4617 * we pass the private data directly when blocking the client: it will
4618 * be accessible later in the reply callback. Normally when blocking with
4619 * RedisModule_BlockClient() the private data to reply to the client is
4620 * passed when calling RedisModule_UnblockClient() but here the unblocking
4621 * is performed by Redis itself, so we need to have some private data before
4622 * hand. The private data is used to store any information about the specific
4623 * unblocking operation that you are implementing. Such information will be
4624 * freed using the free_privdata callback provided by the user.
4625 *
4626 * However the reply callback will be able to access the argument vector of
4627 * the command, so the private data is often not needed.
4628 *
4629 * Note: Under normal circumstances RedisModule_UnblockClient should not be
4630 * called for clients that are blocked on keys (Either the key will
4631 * become ready or a timeout will occur). If for some reason you do want
4632 * to call RedisModule_UnblockClient it is possible: Client will be
4633 * handled as if it were timed-out (You must implement the timeout
4634 * callback in that case).
4635 */
RM_BlockClientOnKeys(RedisModuleCtx * ctx,RedisModuleCmdFunc reply_callback,RedisModuleCmdFunc timeout_callback,void (* free_privdata)(RedisModuleCtx *,void *),long long timeout_ms,RedisModuleString ** keys,int numkeys,void * privdata)4636 RedisModuleBlockedClient *RM_BlockClientOnKeys(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms, RedisModuleString **keys, int numkeys, void *privdata) {
4637 return moduleBlockClient(ctx,reply_callback,timeout_callback,free_privdata,timeout_ms, keys,numkeys,privdata);
4638 }
4639
4640 /* This function is used in order to potentially unblock a client blocked
4641 * on keys with RedisModule_BlockClientOnKeys(). When this function is called,
4642 * all the clients blocked for this key will get their reply_callback called.
4643 *
4644 * Note: The function has no effect if the signaled key doesn't exist. */
RM_SignalKeyAsReady(RedisModuleCtx * ctx,RedisModuleString * key)4645 void RM_SignalKeyAsReady(RedisModuleCtx *ctx, RedisModuleString *key) {
4646 signalKeyAsReady(ctx->client->db, key);
4647 }
4648
4649 /* Implements RM_UnblockClient() and moduleUnblockClient(). */
moduleUnblockClientByHandle(RedisModuleBlockedClient * bc,void * privdata)4650 int moduleUnblockClientByHandle(RedisModuleBlockedClient *bc, void *privdata) {
4651 pthread_mutex_lock(&moduleUnblockedClientsMutex);
4652 if (!bc->blocked_on_keys) bc->privdata = privdata;
4653 bc->unblocked = 1;
4654 listAddNodeTail(moduleUnblockedClients,bc);
4655 if (write(server.module_blocked_pipe[1],"A",1) != 1) {
4656 /* Ignore the error, this is best-effort. */
4657 }
4658 pthread_mutex_unlock(&moduleUnblockedClientsMutex);
4659 return REDISMODULE_OK;
4660 }
4661
4662 /* This API is used by the Redis core to unblock a client that was blocked
4663 * by a module. */
moduleUnblockClient(client * c)4664 void moduleUnblockClient(client *c) {
4665 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
4666 moduleUnblockClientByHandle(bc,NULL);
4667 }
4668
4669 /* Return true if the client 'c' was blocked by a module using
4670 * RM_BlockClientOnKeys(). */
moduleClientIsBlockedOnKeys(client * c)4671 int moduleClientIsBlockedOnKeys(client *c) {
4672 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
4673 return bc->blocked_on_keys;
4674 }
4675
4676 /* Unblock a client blocked by `RedisModule_BlockedClient`. This will trigger
4677 * the reply callbacks to be called in order to reply to the client.
4678 * The 'privdata' argument will be accessible by the reply callback, so
4679 * the caller of this function can pass any value that is needed in order to
4680 * actually reply to the client.
4681 *
4682 * A common usage for 'privdata' is a thread that computes something that
4683 * needs to be passed to the client, included but not limited some slow
4684 * to compute reply or some reply obtained via networking.
4685 *
4686 * Note 1: this function can be called from threads spawned by the module.
4687 *
4688 * Note 2: when we unblock a client that is blocked for keys using the API
4689 * RedisModule_BlockClientOnKeys(), the privdata argument here is not used.
4690 * Unblocking a client that was blocked for keys using this API will still
4691 * require the client to get some reply, so the function will use the
4692 * "timeout" handler in order to do so (The privdata provided in
4693 * RedisModule_BlockClientOnKeys() is accessible from the timeout
4694 * callback via RM_GetBlockedClientPrivateData). */
RM_UnblockClient(RedisModuleBlockedClient * bc,void * privdata)4695 int RM_UnblockClient(RedisModuleBlockedClient *bc, void *privdata) {
4696 if (bc->blocked_on_keys) {
4697 /* In theory the user should always pass the timeout handler as an
4698 * argument, but better to be safe than sorry. */
4699 if (bc->timeout_callback == NULL) return REDISMODULE_ERR;
4700 if (bc->unblocked) return REDISMODULE_OK;
4701 if (bc->client) moduleBlockedClientTimedOut(bc->client);
4702 }
4703 moduleUnblockClientByHandle(bc,privdata);
4704 return REDISMODULE_OK;
4705 }
4706
4707 /* Abort a blocked client blocking operation: the client will be unblocked
4708 * without firing any callback. */
RM_AbortBlock(RedisModuleBlockedClient * bc)4709 int RM_AbortBlock(RedisModuleBlockedClient *bc) {
4710 bc->reply_callback = NULL;
4711 bc->disconnect_callback = NULL;
4712 return RM_UnblockClient(bc,NULL);
4713 }
4714
4715 /* Set a callback that will be called if a blocked client disconnects
4716 * before the module has a chance to call RedisModule_UnblockClient()
4717 *
4718 * Usually what you want to do there, is to cleanup your module state
4719 * so that you can call RedisModule_UnblockClient() safely, otherwise
4720 * the client will remain blocked forever if the timeout is large.
4721 *
4722 * Notes:
4723 *
4724 * 1. It is not safe to call Reply* family functions here, it is also
4725 * useless since the client is gone.
4726 *
4727 * 2. This callback is not called if the client disconnects because of
4728 * a timeout. In such a case, the client is unblocked automatically
4729 * and the timeout callback is called.
4730 */
RM_SetDisconnectCallback(RedisModuleBlockedClient * bc,RedisModuleDisconnectFunc callback)4731 void RM_SetDisconnectCallback(RedisModuleBlockedClient *bc, RedisModuleDisconnectFunc callback) {
4732 bc->disconnect_callback = callback;
4733 }
4734
4735 /* This function will check the moduleUnblockedClients queue in order to
4736 * call the reply callback and really unblock the client.
4737 *
4738 * Clients end into this list because of calls to RM_UnblockClient(),
4739 * however it is possible that while the module was doing work for the
4740 * blocked client, it was terminated by Redis (for timeout or other reasons).
4741 * When this happens the RedisModuleBlockedClient structure in the queue
4742 * will have the 'client' field set to NULL. */
moduleHandleBlockedClients(void)4743 void moduleHandleBlockedClients(void) {
4744 listNode *ln;
4745 RedisModuleBlockedClient *bc;
4746
4747 pthread_mutex_lock(&moduleUnblockedClientsMutex);
4748 /* Here we unblock all the pending clients blocked in modules operations
4749 * so we can read every pending "awake byte" in the pipe. */
4750 char buf[1];
4751 while (read(server.module_blocked_pipe[0],buf,1) == 1);
4752 while (listLength(moduleUnblockedClients)) {
4753 ln = listFirst(moduleUnblockedClients);
4754 bc = ln->value;
4755 client *c = bc->client;
4756 listDelNode(moduleUnblockedClients,ln);
4757 pthread_mutex_unlock(&moduleUnblockedClientsMutex);
4758
4759 /* Release the lock during the loop, as long as we don't
4760 * touch the shared list. */
4761
4762 /* Call the reply callback if the client is valid and we have
4763 * any callback. However the callback is not called if the client
4764 * was blocked on keys (RM_BlockClientOnKeys()), because we already
4765 * called such callback in moduleTryServeClientBlockedOnKey() when
4766 * the key was signaled as ready. */
4767 if (c && !bc->blocked_on_keys && bc->reply_callback) {
4768 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
4769 ctx.flags |= REDISMODULE_CTX_BLOCKED_REPLY;
4770 ctx.blocked_privdata = bc->privdata;
4771 ctx.blocked_ready_key = NULL;
4772 ctx.module = bc->module;
4773 ctx.client = bc->client;
4774 ctx.blocked_client = bc;
4775 bc->reply_callback(&ctx,(void**)c->argv,c->argc);
4776 moduleFreeContext(&ctx);
4777 }
4778
4779 /* Free privdata if any. */
4780 if (bc->privdata && bc->free_privdata) {
4781 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
4782 if (c == NULL)
4783 ctx.flags |= REDISMODULE_CTX_BLOCKED_DISCONNECTED;
4784 ctx.blocked_privdata = bc->privdata;
4785 ctx.module = bc->module;
4786 ctx.client = bc->client;
4787 bc->free_privdata(&ctx,bc->privdata);
4788 moduleFreeContext(&ctx);
4789 }
4790
4791 /* It is possible that this blocked client object accumulated
4792 * replies to send to the client in a thread safe context.
4793 * We need to glue such replies to the client output buffer and
4794 * free the temporary client we just used for the replies. */
4795 if (c) AddReplyFromClient(c, bc->reply_client);
4796 freeClient(bc->reply_client);
4797
4798 if (c != NULL) {
4799 /* Before unblocking the client, set the disconnect callback
4800 * to NULL, because if we reached this point, the client was
4801 * properly unblocked by the module. */
4802 bc->disconnect_callback = NULL;
4803 unblockClient(c);
4804 /* Put the client in the list of clients that need to write
4805 * if there are pending replies here. This is needed since
4806 * during a non blocking command the client may receive output. */
4807 if (clientHasPendingReplies(c) &&
4808 !(c->flags & CLIENT_PENDING_WRITE))
4809 {
4810 c->flags |= CLIENT_PENDING_WRITE;
4811 listAddNodeHead(server.clients_pending_write,c);
4812 }
4813 }
4814
4815 /* Free 'bc' only after unblocking the client, since it is
4816 * referenced in the client blocking context, and must be valid
4817 * when calling unblockClient(). */
4818 bc->module->blocked_clients--;
4819 zfree(bc);
4820
4821 /* Lock again before to iterate the loop. */
4822 pthread_mutex_lock(&moduleUnblockedClientsMutex);
4823 }
4824 pthread_mutex_unlock(&moduleUnblockedClientsMutex);
4825 }
4826
4827 /* Called when our client timed out. After this function unblockClient()
4828 * is called, and it will invalidate the blocked client. So this function
4829 * does not need to do any cleanup. Eventually the module will call the
4830 * API to unblock the client and the memory will be released. */
moduleBlockedClientTimedOut(client * c)4831 void moduleBlockedClientTimedOut(client *c) {
4832 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
4833
4834 /* Protect against re-processing: don't serve clients that are already
4835 * in the unblocking list for any reason (including RM_UnblockClient()
4836 * explicit call). See #6798. */
4837 if (bc->unblocked) return;
4838
4839 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
4840 ctx.flags |= REDISMODULE_CTX_BLOCKED_TIMEOUT;
4841 ctx.module = bc->module;
4842 ctx.client = bc->client;
4843 ctx.blocked_client = bc;
4844 ctx.blocked_privdata = bc->privdata;
4845 bc->timeout_callback(&ctx,(void**)c->argv,c->argc);
4846 moduleFreeContext(&ctx);
4847 /* For timeout events, we do not want to call the disconnect callback,
4848 * because the blocked client will be automatically disconnected in
4849 * this case, and the user can still hook using the timeout callback. */
4850 bc->disconnect_callback = NULL;
4851 }
4852
4853 /* Return non-zero if a module command was called in order to fill the
4854 * reply for a blocked client. */
RM_IsBlockedReplyRequest(RedisModuleCtx * ctx)4855 int RM_IsBlockedReplyRequest(RedisModuleCtx *ctx) {
4856 return (ctx->flags & REDISMODULE_CTX_BLOCKED_REPLY) != 0;
4857 }
4858
4859 /* Return non-zero if a module command was called in order to fill the
4860 * reply for a blocked client that timed out. */
RM_IsBlockedTimeoutRequest(RedisModuleCtx * ctx)4861 int RM_IsBlockedTimeoutRequest(RedisModuleCtx *ctx) {
4862 return (ctx->flags & REDISMODULE_CTX_BLOCKED_TIMEOUT) != 0;
4863 }
4864
4865 /* Get the private data set by RedisModule_UnblockClient() */
RM_GetBlockedClientPrivateData(RedisModuleCtx * ctx)4866 void *RM_GetBlockedClientPrivateData(RedisModuleCtx *ctx) {
4867 return ctx->blocked_privdata;
4868 }
4869
4870 /* Get the key that is ready when the reply callback is called in the context
4871 * of a client blocked by RedisModule_BlockClientOnKeys(). */
RM_GetBlockedClientReadyKey(RedisModuleCtx * ctx)4872 RedisModuleString *RM_GetBlockedClientReadyKey(RedisModuleCtx *ctx) {
4873 return ctx->blocked_ready_key;
4874 }
4875
4876 /* Get the blocked client associated with a given context.
4877 * This is useful in the reply and timeout callbacks of blocked clients,
4878 * before sometimes the module has the blocked client handle references
4879 * around, and wants to cleanup it. */
RM_GetBlockedClientHandle(RedisModuleCtx * ctx)4880 RedisModuleBlockedClient *RM_GetBlockedClientHandle(RedisModuleCtx *ctx) {
4881 return ctx->blocked_client;
4882 }
4883
4884 /* Return true if when the free callback of a blocked client is called,
4885 * the reason for the client to be unblocked is that it disconnected
4886 * while it was blocked. */
RM_BlockedClientDisconnected(RedisModuleCtx * ctx)4887 int RM_BlockedClientDisconnected(RedisModuleCtx *ctx) {
4888 return (ctx->flags & REDISMODULE_CTX_BLOCKED_DISCONNECTED) != 0;
4889 }
4890
4891 /* --------------------------------------------------------------------------
4892 * Thread Safe Contexts
4893 * -------------------------------------------------------------------------- */
4894
4895 /* Return a context which can be used inside threads to make Redis context
4896 * calls with certain modules APIs. If 'bc' is not NULL then the module will
4897 * be bound to a blocked client, and it will be possible to use the
4898 * `RedisModule_Reply*` family of functions to accumulate a reply for when the
4899 * client will be unblocked. Otherwise the thread safe context will be
4900 * detached by a specific client.
4901 *
4902 * To call non-reply APIs, the thread safe context must be prepared with:
4903 *
4904 * RedisModule_ThreadSafeContextLock(ctx);
4905 * ... make your call here ...
4906 * RedisModule_ThreadSafeContextUnlock(ctx);
4907 *
4908 * This is not needed when using `RedisModule_Reply*` functions, assuming
4909 * that a blocked client was used when the context was created, otherwise
4910 * no RedisModule_Reply* call should be made at all.
4911 *
4912 * NOTE: If you're creating a detached thread safe context (bc is NULL),
4913 * consider using `RM_GetDetachedThreadSafeContext` which will also retain
4914 * the module ID and thus be more useful for logging. */
RM_GetThreadSafeContext(RedisModuleBlockedClient * bc)4915 RedisModuleCtx *RM_GetThreadSafeContext(RedisModuleBlockedClient *bc) {
4916 RedisModuleCtx *ctx = zmalloc(sizeof(*ctx));
4917 RedisModuleCtx empty = REDISMODULE_CTX_INIT;
4918 memcpy(ctx,&empty,sizeof(empty));
4919 if (bc) {
4920 ctx->blocked_client = bc;
4921 ctx->module = bc->module;
4922 }
4923 ctx->flags |= REDISMODULE_CTX_THREAD_SAFE;
4924 /* Even when the context is associated with a blocked client, we can't
4925 * access it safely from another thread, so we create a fake client here
4926 * in order to keep things like the currently selected database and similar
4927 * things. */
4928 ctx->client = createClient(NULL);
4929 if (bc) {
4930 selectDb(ctx->client,bc->dbid);
4931 if (bc->client) ctx->client->id = bc->client->id;
4932 }
4933 return ctx;
4934 }
4935
4936 /* Return a detached thread safe context that is not associated with any
4937 * specific blocked client, but is associated with the module's context.
4938 *
4939 * This is useful for modules that wish to hold a global context over
4940 * a long term, for purposes such as logging. */
RM_GetDetachedThreadSafeContext(RedisModuleCtx * ctx)4941 RedisModuleCtx *RM_GetDetachedThreadSafeContext(RedisModuleCtx *ctx) {
4942 RedisModuleCtx *new_ctx = zmalloc(sizeof(*new_ctx));
4943 RedisModuleCtx empty = REDISMODULE_CTX_INIT;
4944 memcpy(new_ctx,&empty,sizeof(empty));
4945 new_ctx->module = ctx->module;
4946 new_ctx->flags |= REDISMODULE_CTX_THREAD_SAFE;
4947 new_ctx->client = createClient(NULL);
4948 return new_ctx;
4949 }
4950
4951 /* Release a thread safe context. */
RM_FreeThreadSafeContext(RedisModuleCtx * ctx)4952 void RM_FreeThreadSafeContext(RedisModuleCtx *ctx) {
4953 moduleFreeContext(ctx);
4954 zfree(ctx);
4955 }
4956
4957 /* Acquire the server lock before executing a thread safe API call.
4958 * This is not needed for `RedisModule_Reply*` calls when there is
4959 * a blocked client connected to the thread safe context. */
RM_ThreadSafeContextLock(RedisModuleCtx * ctx)4960 void RM_ThreadSafeContextLock(RedisModuleCtx *ctx) {
4961 UNUSED(ctx);
4962 moduleAcquireGIL();
4963 }
4964
4965 /* Similar to RM_ThreadSafeContextLock but this function
4966 * would not block if the server lock is already acquired.
4967 *
4968 * If successful (lock acquired) REDISMODULE_OK is returned,
4969 * otherwise REDISMODULE_ERR is returned and errno is set
4970 * accordingly. */
RM_ThreadSafeContextTryLock(RedisModuleCtx * ctx)4971 int RM_ThreadSafeContextTryLock(RedisModuleCtx *ctx) {
4972 UNUSED(ctx);
4973
4974 int res = moduleTryAcquireGIL();
4975 if(res != 0) {
4976 errno = res;
4977 return REDISMODULE_ERR;
4978 }
4979 return REDISMODULE_OK;
4980 }
4981
4982 /* Release the server lock after a thread safe API call was executed. */
RM_ThreadSafeContextUnlock(RedisModuleCtx * ctx)4983 void RM_ThreadSafeContextUnlock(RedisModuleCtx *ctx) {
4984 UNUSED(ctx);
4985 moduleReleaseGIL();
4986 }
4987
moduleAcquireGIL(void)4988 void moduleAcquireGIL(void) {
4989 pthread_mutex_lock(&moduleGIL);
4990 }
4991
moduleTryAcquireGIL(void)4992 int moduleTryAcquireGIL(void) {
4993 return pthread_mutex_trylock(&moduleGIL);
4994 }
4995
moduleReleaseGIL(void)4996 void moduleReleaseGIL(void) {
4997 pthread_mutex_unlock(&moduleGIL);
4998 }
4999
5000
5001 /* --------------------------------------------------------------------------
5002 * Module Keyspace Notifications API
5003 * -------------------------------------------------------------------------- */
5004
5005 /* Subscribe to keyspace notifications. This is a low-level version of the
5006 * keyspace-notifications API. A module can register callbacks to be notified
5007 * when keyspace events occur.
5008 *
5009 * Notification events are filtered by their type (string events, set events,
5010 * etc), and the subscriber callback receives only events that match a specific
5011 * mask of event types.
5012 *
5013 * When subscribing to notifications with RedisModule_SubscribeToKeyspaceEvents
5014 * the module must provide an event type-mask, denoting the events the subscriber
5015 * is interested in. This can be an ORed mask of any of the following flags:
5016 *
5017 * - REDISMODULE_NOTIFY_GENERIC: Generic commands like DEL, EXPIRE, RENAME
5018 * - REDISMODULE_NOTIFY_STRING: String events
5019 * - REDISMODULE_NOTIFY_LIST: List events
5020 * - REDISMODULE_NOTIFY_SET: Set events
5021 * - REDISMODULE_NOTIFY_HASH: Hash events
5022 * - REDISMODULE_NOTIFY_ZSET: Sorted Set events
5023 * - REDISMODULE_NOTIFY_EXPIRED: Expiration events
5024 * - REDISMODULE_NOTIFY_EVICTED: Eviction events
5025 * - REDISMODULE_NOTIFY_STREAM: Stream events
5026 * - REDISMODULE_NOTIFY_KEYMISS: Key-miss events
5027 * - REDISMODULE_NOTIFY_ALL: All events (Excluding REDISMODULE_NOTIFY_KEYMISS)
5028 * - REDISMODULE_NOTIFY_LOADED: A special notification available only for modules,
5029 * indicates that the key was loaded from persistence.
5030 * Notice, when this event fires, the given key
5031 * can not be retained, use RM_CreateStringFromString
5032 * instead.
5033 *
5034 * We do not distinguish between key events and keyspace events, and it is up
5035 * to the module to filter the actions taken based on the key.
5036 *
5037 * The subscriber signature is:
5038 *
5039 * int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type,
5040 * const char *event,
5041 * RedisModuleString *key);
5042 *
5043 * `type` is the event type bit, that must match the mask given at registration
5044 * time. The event string is the actual command being executed, and key is the
5045 * relevant Redis key.
5046 *
5047 * Notification callback gets executed with a redis context that can not be
5048 * used to send anything to the client, and has the db number where the event
5049 * occurred as its selected db number.
5050 *
5051 * Notice that it is not necessary to enable notifications in redis.conf for
5052 * module notifications to work.
5053 *
5054 * Warning: the notification callbacks are performed in a synchronous manner,
5055 * so notification callbacks must to be fast, or they would slow Redis down.
5056 * If you need to take long actions, use threads to offload them.
5057 *
5058 * See https://redis.io/topics/notifications for more information.
5059 */
RM_SubscribeToKeyspaceEvents(RedisModuleCtx * ctx,int types,RedisModuleNotificationFunc callback)5060 int RM_SubscribeToKeyspaceEvents(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc callback) {
5061 RedisModuleKeyspaceSubscriber *sub = zmalloc(sizeof(*sub));
5062 sub->module = ctx->module;
5063 sub->event_mask = types;
5064 sub->notify_callback = callback;
5065 sub->active = 0;
5066
5067 listAddNodeTail(moduleKeyspaceSubscribers, sub);
5068 return REDISMODULE_OK;
5069 }
5070
5071 /* Get the configured bitmap of notify-keyspace-events (Could be used
5072 * for additional filtering in RedisModuleNotificationFunc) */
RM_GetNotifyKeyspaceEvents()5073 int RM_GetNotifyKeyspaceEvents() {
5074 return server.notify_keyspace_events;
5075 }
5076
5077 /* Expose notifyKeyspaceEvent to modules */
RM_NotifyKeyspaceEvent(RedisModuleCtx * ctx,int type,const char * event,RedisModuleString * key)5078 int RM_NotifyKeyspaceEvent(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
5079 if (!ctx || !ctx->client)
5080 return REDISMODULE_ERR;
5081 notifyKeyspaceEvent(type, (char *)event, key, ctx->client->db->id);
5082 return REDISMODULE_OK;
5083 }
5084
5085 /* Dispatcher for keyspace notifications to module subscriber functions.
5086 * This gets called only if at least one module requested to be notified on
5087 * keyspace notifications */
moduleNotifyKeyspaceEvent(int type,const char * event,robj * key,int dbid)5088 void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) {
5089 /* Don't do anything if there aren't any subscribers */
5090 if (listLength(moduleKeyspaceSubscribers) == 0) return;
5091
5092 listIter li;
5093 listNode *ln;
5094 listRewind(moduleKeyspaceSubscribers,&li);
5095
5096 /* Remove irrelevant flags from the type mask */
5097 type &= ~(NOTIFY_KEYEVENT | NOTIFY_KEYSPACE);
5098
5099 while((ln = listNext(&li))) {
5100 RedisModuleKeyspaceSubscriber *sub = ln->value;
5101 /* Only notify subscribers on events matching they registration,
5102 * and avoid subscribers triggering themselves */
5103 if ((sub->event_mask & type) && sub->active == 0) {
5104 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
5105 ctx.module = sub->module;
5106 ctx.client = moduleFreeContextReusedClient;
5107 selectDb(ctx.client, dbid);
5108
5109 /* mark the handler as active to avoid reentrant loops.
5110 * If the subscriber performs an action triggering itself,
5111 * it will not be notified about it. */
5112 sub->active = 1;
5113 sub->notify_callback(&ctx, type, event, key);
5114 sub->active = 0;
5115 moduleFreeContext(&ctx);
5116 }
5117 }
5118 }
5119
5120 /* Unsubscribe any notification subscribers this module has upon unloading */
moduleUnsubscribeNotifications(RedisModule * module)5121 void moduleUnsubscribeNotifications(RedisModule *module) {
5122 listIter li;
5123 listNode *ln;
5124 listRewind(moduleKeyspaceSubscribers,&li);
5125 while((ln = listNext(&li))) {
5126 RedisModuleKeyspaceSubscriber *sub = ln->value;
5127 if (sub->module == module) {
5128 listDelNode(moduleKeyspaceSubscribers, ln);
5129 zfree(sub);
5130 }
5131 }
5132 }
5133
5134 /* --------------------------------------------------------------------------
5135 * Modules Cluster API
5136 * -------------------------------------------------------------------------- */
5137
5138 /* The Cluster message callback function pointer type. */
5139 typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len);
5140
5141 /* This structure identifies a registered caller: it must match a given module
5142 * ID, for a given message type. The callback function is just the function
5143 * that was registered as receiver. */
5144 typedef struct moduleClusterReceiver {
5145 uint64_t module_id;
5146 RedisModuleClusterMessageReceiver callback;
5147 struct RedisModule *module;
5148 struct moduleClusterReceiver *next;
5149 } moduleClusterReceiver;
5150
5151 typedef struct moduleClusterNodeInfo {
5152 int flags;
5153 char ip[NET_IP_STR_LEN];
5154 int port;
5155 char master_id[40]; /* Only if flags & REDISMODULE_NODE_MASTER is true. */
5156 } mdouleClusterNodeInfo;
5157
5158 /* We have an array of message types: each bucket is a linked list of
5159 * configured receivers. */
5160 static moduleClusterReceiver *clusterReceivers[UINT8_MAX];
5161
5162 /* Dispatch the message to the right module receiver. */
moduleCallClusterReceivers(const char * sender_id,uint64_t module_id,uint8_t type,const unsigned char * payload,uint32_t len)5163 void moduleCallClusterReceivers(const char *sender_id, uint64_t module_id, uint8_t type, const unsigned char *payload, uint32_t len) {
5164 moduleClusterReceiver *r = clusterReceivers[type];
5165 while(r) {
5166 if (r->module_id == module_id) {
5167 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
5168 ctx.module = r->module;
5169 ctx.client = moduleFreeContextReusedClient;
5170 selectDb(ctx.client, 0);
5171 r->callback(&ctx,sender_id,type,payload,len);
5172 moduleFreeContext(&ctx);
5173 return;
5174 }
5175 r = r->next;
5176 }
5177 }
5178
5179 /* Register a callback receiver for cluster messages of type 'type'. If there
5180 * was already a registered callback, this will replace the callback function
5181 * with the one provided, otherwise if the callback is set to NULL and there
5182 * is already a callback for this function, the callback is unregistered
5183 * (so this API call is also used in order to delete the receiver). */
RM_RegisterClusterMessageReceiver(RedisModuleCtx * ctx,uint8_t type,RedisModuleClusterMessageReceiver callback)5184 void RM_RegisterClusterMessageReceiver(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback) {
5185 if (!server.cluster_enabled) return;
5186
5187 uint64_t module_id = moduleTypeEncodeId(ctx->module->name,0);
5188 moduleClusterReceiver *r = clusterReceivers[type], *prev = NULL;
5189 while(r) {
5190 if (r->module_id == module_id) {
5191 /* Found! Set or delete. */
5192 if (callback) {
5193 r->callback = callback;
5194 } else {
5195 /* Delete the receiver entry if the user is setting
5196 * it to NULL. Just unlink the receiver node from the
5197 * linked list. */
5198 if (prev)
5199 prev->next = r->next;
5200 else
5201 clusterReceivers[type]->next = r->next;
5202 zfree(r);
5203 }
5204 return;
5205 }
5206 prev = r;
5207 r = r->next;
5208 }
5209
5210 /* Not found, let's add it. */
5211 if (callback) {
5212 r = zmalloc(sizeof(*r));
5213 r->module_id = module_id;
5214 r->module = ctx->module;
5215 r->callback = callback;
5216 r->next = clusterReceivers[type];
5217 clusterReceivers[type] = r;
5218 }
5219 }
5220
5221 /* Send a message to all the nodes in the cluster if `target` is NULL, otherwise
5222 * at the specified target, which is a REDISMODULE_NODE_ID_LEN bytes node ID, as
5223 * returned by the receiver callback or by the nodes iteration functions.
5224 *
5225 * The function returns REDISMODULE_OK if the message was successfully sent,
5226 * otherwise if the node is not connected or such node ID does not map to any
5227 * known cluster node, REDISMODULE_ERR is returned. */
RM_SendClusterMessage(RedisModuleCtx * ctx,char * target_id,uint8_t type,unsigned char * msg,uint32_t len)5228 int RM_SendClusterMessage(RedisModuleCtx *ctx, char *target_id, uint8_t type, unsigned char *msg, uint32_t len) {
5229 if (!server.cluster_enabled) return REDISMODULE_ERR;
5230 uint64_t module_id = moduleTypeEncodeId(ctx->module->name,0);
5231 if (clusterSendModuleMessageToTarget(target_id,module_id,type,msg,len) == C_OK)
5232 return REDISMODULE_OK;
5233 else
5234 return REDISMODULE_ERR;
5235 }
5236
5237 /* Return an array of string pointers, each string pointer points to a cluster
5238 * node ID of exactly REDISMODULE_NODE_ID_SIZE bytes (without any null term).
5239 * The number of returned node IDs is stored into `*numnodes`.
5240 * However if this function is called by a module not running an a Redis
5241 * instance with Redis Cluster enabled, NULL is returned instead.
5242 *
5243 * The IDs returned can be used with RedisModule_GetClusterNodeInfo() in order
5244 * to get more information about single nodes.
5245 *
5246 * The array returned by this function must be freed using the function
5247 * RedisModule_FreeClusterNodesList().
5248 *
5249 * Example:
5250 *
5251 * size_t count, j;
5252 * char **ids = RedisModule_GetClusterNodesList(ctx,&count);
5253 * for (j = 0; j < count; j++) {
5254 * RedisModule_Log("notice","Node %.*s",
5255 * REDISMODULE_NODE_ID_LEN,ids[j]);
5256 * }
5257 * RedisModule_FreeClusterNodesList(ids);
5258 */
RM_GetClusterNodesList(RedisModuleCtx * ctx,size_t * numnodes)5259 char **RM_GetClusterNodesList(RedisModuleCtx *ctx, size_t *numnodes) {
5260 UNUSED(ctx);
5261
5262 if (!server.cluster_enabled) return NULL;
5263 size_t count = dictSize(server.cluster->nodes);
5264 char **ids = zmalloc((count+1)*REDISMODULE_NODE_ID_LEN);
5265 dictIterator *di = dictGetIterator(server.cluster->nodes);
5266 dictEntry *de;
5267 int j = 0;
5268 while((de = dictNext(di)) != NULL) {
5269 clusterNode *node = dictGetVal(de);
5270 if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) continue;
5271 ids[j] = zmalloc(REDISMODULE_NODE_ID_LEN);
5272 memcpy(ids[j],node->name,REDISMODULE_NODE_ID_LEN);
5273 j++;
5274 }
5275 *numnodes = j;
5276 ids[j] = NULL; /* Null term so that FreeClusterNodesList does not need
5277 * to also get the count argument. */
5278 dictReleaseIterator(di);
5279 return ids;
5280 }
5281
5282 /* Free the node list obtained with RedisModule_GetClusterNodesList. */
RM_FreeClusterNodesList(char ** ids)5283 void RM_FreeClusterNodesList(char **ids) {
5284 if (ids == NULL) return;
5285 for (int j = 0; ids[j]; j++) zfree(ids[j]);
5286 zfree(ids);
5287 }
5288
5289 /* Return this node ID (REDISMODULE_CLUSTER_ID_LEN bytes) or NULL if the cluster
5290 * is disabled. */
RM_GetMyClusterID(void)5291 const char *RM_GetMyClusterID(void) {
5292 if (!server.cluster_enabled) return NULL;
5293 return server.cluster->myself->name;
5294 }
5295
5296 /* Return the number of nodes in the cluster, regardless of their state
5297 * (handshake, noaddress, ...) so that the number of active nodes may actually
5298 * be smaller, but not greater than this number. If the instance is not in
5299 * cluster mode, zero is returned. */
RM_GetClusterSize(void)5300 size_t RM_GetClusterSize(void) {
5301 if (!server.cluster_enabled) return 0;
5302 return dictSize(server.cluster->nodes);
5303 }
5304
5305 /* Populate the specified info for the node having as ID the specified 'id',
5306 * then returns REDISMODULE_OK. Otherwise if the node ID does not exist from
5307 * the POV of this local node, REDISMODULE_ERR is returned.
5308 *
5309 * The arguments ip, master_id, port and flags can be NULL in case we don't
5310 * need to populate back certain info. If an ip and master_id (only populated
5311 * if the instance is a slave) are specified, they point to buffers holding
5312 * at least REDISMODULE_NODE_ID_LEN bytes. The strings written back as ip
5313 * and master_id are not null terminated.
5314 *
5315 * The list of flags reported is the following:
5316 *
5317 * * REDISMODULE_NODE_MYSELF This node
5318 * * REDISMODULE_NODE_MASTER The node is a master
5319 * * REDISMODULE_NODE_SLAVE The node is a replica
5320 * * REDISMODULE_NODE_PFAIL We see the node as failing
5321 * * REDISMODULE_NODE_FAIL The cluster agrees the node is failing
5322 * * REDISMODULE_NODE_NOFAILOVER The slave is configured to never failover
5323 */
5324
5325 clusterNode *clusterLookupNode(const char *name); /* We need access to internals */
5326
RM_GetClusterNodeInfo(RedisModuleCtx * ctx,const char * id,char * ip,char * master_id,int * port,int * flags)5327 int RM_GetClusterNodeInfo(RedisModuleCtx *ctx, const char *id, char *ip, char *master_id, int *port, int *flags) {
5328 UNUSED(ctx);
5329
5330 clusterNode *node = clusterLookupNode(id);
5331 if (node == NULL ||
5332 node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE))
5333 {
5334 return REDISMODULE_ERR;
5335 }
5336
5337 if (ip) strncpy(ip,node->ip,NET_IP_STR_LEN);
5338
5339 if (master_id) {
5340 /* If the information is not available, the function will set the
5341 * field to zero bytes, so that when the field can't be populated the
5342 * function kinda remains predictable. */
5343 if (node->flags & CLUSTER_NODE_MASTER && node->slaveof)
5344 memcpy(master_id,node->slaveof->name,REDISMODULE_NODE_ID_LEN);
5345 else
5346 memset(master_id,0,REDISMODULE_NODE_ID_LEN);
5347 }
5348 if (port) *port = node->port;
5349
5350 /* As usually we have to remap flags for modules, in order to ensure
5351 * we can provide binary compatibility. */
5352 if (flags) {
5353 *flags = 0;
5354 if (node->flags & CLUSTER_NODE_MYSELF) *flags |= REDISMODULE_NODE_MYSELF;
5355 if (node->flags & CLUSTER_NODE_MASTER) *flags |= REDISMODULE_NODE_MASTER;
5356 if (node->flags & CLUSTER_NODE_SLAVE) *flags |= REDISMODULE_NODE_SLAVE;
5357 if (node->flags & CLUSTER_NODE_PFAIL) *flags |= REDISMODULE_NODE_PFAIL;
5358 if (node->flags & CLUSTER_NODE_FAIL) *flags |= REDISMODULE_NODE_FAIL;
5359 if (node->flags & CLUSTER_NODE_NOFAILOVER) *flags |= REDISMODULE_NODE_NOFAILOVER;
5360 }
5361 return REDISMODULE_OK;
5362 }
5363
5364 /* Set Redis Cluster flags in order to change the normal behavior of
5365 * Redis Cluster, especially with the goal of disabling certain functions.
5366 * This is useful for modules that use the Cluster API in order to create
5367 * a different distributed system, but still want to use the Redis Cluster
5368 * message bus. Flags that can be set:
5369 *
5370 * CLUSTER_MODULE_FLAG_NO_FAILOVER
5371 * CLUSTER_MODULE_FLAG_NO_REDIRECTION
5372 *
5373 * With the following effects:
5374 *
5375 * NO_FAILOVER: prevent Redis Cluster slaves to failover a failing master.
5376 * Also disables the replica migration feature.
5377 *
5378 * NO_REDIRECTION: Every node will accept any key, without trying to perform
5379 * partitioning according to the user Redis Cluster algorithm.
5380 * Slots informations will still be propagated across the
5381 * cluster, but without effects. */
RM_SetClusterFlags(RedisModuleCtx * ctx,uint64_t flags)5382 void RM_SetClusterFlags(RedisModuleCtx *ctx, uint64_t flags) {
5383 UNUSED(ctx);
5384 if (flags & REDISMODULE_CLUSTER_FLAG_NO_FAILOVER)
5385 server.cluster_module_flags |= CLUSTER_MODULE_FLAG_NO_FAILOVER;
5386 if (flags & REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION)
5387 server.cluster_module_flags |= CLUSTER_MODULE_FLAG_NO_REDIRECTION;
5388 }
5389
5390 /* --------------------------------------------------------------------------
5391 * Modules Timers API
5392 *
5393 * Module timers are an high precision "green timers" abstraction where
5394 * every module can register even millions of timers without problems, even if
5395 * the actual event loop will just have a single timer that is used to awake the
5396 * module timers subsystem in order to process the next event.
5397 *
5398 * All the timers are stored into a radix tree, ordered by expire time, when
5399 * the main Redis event loop timer callback is called, we try to process all
5400 * the timers already expired one after the other. Then we re-enter the event
5401 * loop registering a timer that will expire when the next to process module
5402 * timer will expire.
5403 *
5404 * Every time the list of active timers drops to zero, we unregister the
5405 * main event loop timer, so that there is no overhead when such feature is
5406 * not used.
5407 * -------------------------------------------------------------------------- */
5408
5409 static rax *Timers; /* The radix tree of all the timers sorted by expire. */
5410 long long aeTimer = -1; /* Main event loop (ae.c) timer identifier. */
5411
5412 typedef void (*RedisModuleTimerProc)(RedisModuleCtx *ctx, void *data);
5413
5414 /* The timer descriptor, stored as value in the radix tree. */
5415 typedef struct RedisModuleTimer {
5416 RedisModule *module; /* Module reference. */
5417 RedisModuleTimerProc callback; /* The callback to invoke on expire. */
5418 void *data; /* Private data for the callback. */
5419 int dbid; /* Database number selected by the original client. */
5420 } RedisModuleTimer;
5421
5422 /* This is the timer handler that is called by the main event loop. We schedule
5423 * this timer to be called when the nearest of our module timers will expire. */
moduleTimerHandler(struct aeEventLoop * eventLoop,long long id,void * clientData)5424 int moduleTimerHandler(struct aeEventLoop *eventLoop, long long id, void *clientData) {
5425 UNUSED(eventLoop);
5426 UNUSED(id);
5427 UNUSED(clientData);
5428
5429 /* To start let's try to fire all the timers already expired. */
5430 raxIterator ri;
5431 raxStart(&ri,Timers);
5432 uint64_t now = ustime();
5433 long long next_period = 0;
5434 while(1) {
5435 raxSeek(&ri,"^",NULL,0);
5436 if (!raxNext(&ri)) break;
5437 uint64_t expiretime;
5438 memcpy(&expiretime,ri.key,sizeof(expiretime));
5439 expiretime = ntohu64(expiretime);
5440 if (now >= expiretime) {
5441 RedisModuleTimer *timer = ri.data;
5442 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
5443
5444 ctx.module = timer->module;
5445 ctx.client = moduleFreeContextReusedClient;
5446 selectDb(ctx.client, timer->dbid);
5447 timer->callback(&ctx,timer->data);
5448 moduleFreeContext(&ctx);
5449 raxRemove(Timers,(unsigned char*)ri.key,ri.key_len,NULL);
5450 zfree(timer);
5451 } else {
5452 /* We call ustime() again instead of using the cached 'now' so that
5453 * 'next_period' isn't affected by the time it took to execute
5454 * previous calls to 'callback.
5455 * We need to cast 'expiretime' so that the compiler will not treat
5456 * the difference as unsigned (Causing next_period to be huge) in
5457 * case expiretime < ustime() */
5458 next_period = ((long long)expiretime-ustime())/1000; /* Scale to milliseconds. */
5459 break;
5460 }
5461 }
5462 raxStop(&ri);
5463
5464 /* Reschedule the next timer or cancel it. */
5465 if (next_period <= 0) next_period = 1;
5466 return (raxSize(Timers) > 0) ? next_period : AE_NOMORE;
5467 }
5468
5469 /* Create a new timer that will fire after `period` milliseconds, and will call
5470 * the specified function using `data` as argument. The returned timer ID can be
5471 * used to get information from the timer or to stop it before it fires.
5472 * Note that for the common use case of a repeating timer (Re-registration
5473 * of the timer inside the RedisModuleTimerProc callback) it matters when
5474 * this API is called:
5475 * If it is called at the beginning of 'callback' it means
5476 * the event will triggered every 'period'.
5477 * If it is called at the end of 'callback' it means
5478 * there will 'period' milliseconds gaps between events.
5479 * (If the time it takes to execute 'callback' is negligible the two
5480 * statements above mean the same) */
RM_CreateTimer(RedisModuleCtx * ctx,mstime_t period,RedisModuleTimerProc callback,void * data)5481 RedisModuleTimerID RM_CreateTimer(RedisModuleCtx *ctx, mstime_t period, RedisModuleTimerProc callback, void *data) {
5482 RedisModuleTimer *timer = zmalloc(sizeof(*timer));
5483 timer->module = ctx->module;
5484 timer->callback = callback;
5485 timer->data = data;
5486 timer->dbid = ctx->client ? ctx->client->db->id : 0;
5487 uint64_t expiretime = ustime()+period*1000;
5488 uint64_t key;
5489
5490 while(1) {
5491 key = htonu64(expiretime);
5492 if (raxFind(Timers, (unsigned char*)&key,sizeof(key)) == raxNotFound) {
5493 raxInsert(Timers,(unsigned char*)&key,sizeof(key),timer,NULL);
5494 break;
5495 } else {
5496 expiretime++;
5497 }
5498 }
5499
5500 /* We need to install the main event loop timer if it's not already
5501 * installed, or we may need to refresh its period if we just installed
5502 * a timer that will expire sooner than any other else (i.e. the timer
5503 * we just installed is the first timer in the Timers rax). */
5504 if (aeTimer != -1) {
5505 raxIterator ri;
5506 raxStart(&ri,Timers);
5507 raxSeek(&ri,"^",NULL,0);
5508 raxNext(&ri);
5509 if (memcmp(ri.key,&key,sizeof(key)) == 0) {
5510 /* This is the first key, we need to re-install the timer according
5511 * to the just added event. */
5512 aeDeleteTimeEvent(server.el,aeTimer);
5513 aeTimer = -1;
5514 }
5515 raxStop(&ri);
5516 }
5517
5518 /* If we have no main timer (the old one was invalidated, or this is the
5519 * first module timer we have), install one. */
5520 if (aeTimer == -1)
5521 aeTimer = aeCreateTimeEvent(server.el,period,moduleTimerHandler,NULL,NULL);
5522
5523 return key;
5524 }
5525
5526 /* Stop a timer, returns REDISMODULE_OK if the timer was found, belonged to the
5527 * calling module, and was stopped, otherwise REDISMODULE_ERR is returned.
5528 * If not NULL, the data pointer is set to the value of the data argument when
5529 * the timer was created. */
RM_StopTimer(RedisModuleCtx * ctx,RedisModuleTimerID id,void ** data)5530 int RM_StopTimer(RedisModuleCtx *ctx, RedisModuleTimerID id, void **data) {
5531 RedisModuleTimer *timer = raxFind(Timers,(unsigned char*)&id,sizeof(id));
5532 if (timer == raxNotFound || timer->module != ctx->module)
5533 return REDISMODULE_ERR;
5534 if (data) *data = timer->data;
5535 raxRemove(Timers,(unsigned char*)&id,sizeof(id),NULL);
5536 zfree(timer);
5537 return REDISMODULE_OK;
5538 }
5539
5540 /* Obtain information about a timer: its remaining time before firing
5541 * (in milliseconds), and the private data pointer associated with the timer.
5542 * If the timer specified does not exist or belongs to a different module
5543 * no information is returned and the function returns REDISMODULE_ERR, otherwise
5544 * REDISMODULE_OK is returned. The arguments remaining or data can be NULL if
5545 * the caller does not need certain information. */
RM_GetTimerInfo(RedisModuleCtx * ctx,RedisModuleTimerID id,uint64_t * remaining,void ** data)5546 int RM_GetTimerInfo(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remaining, void **data) {
5547 RedisModuleTimer *timer = raxFind(Timers,(unsigned char*)&id,sizeof(id));
5548 if (timer == raxNotFound || timer->module != ctx->module)
5549 return REDISMODULE_ERR;
5550 if (remaining) {
5551 int64_t rem = ntohu64(id)-ustime();
5552 if (rem < 0) rem = 0;
5553 *remaining = rem/1000; /* Scale to milliseconds. */
5554 }
5555 if (data) *data = timer->data;
5556 return REDISMODULE_OK;
5557 }
5558
5559 /* --------------------------------------------------------------------------
5560 * Modules ACL API
5561 *
5562 * Implements a hook into the authentication and authorization within Redis.
5563 * --------------------------------------------------------------------------*/
5564
5565 /* This function is called when a client's user has changed and invokes the
5566 * client's user changed callback if it was set. This callback should
5567 * cleanup any state the module was tracking about this client.
5568 *
5569 * A client's user can be changed through the AUTH command, module
5570 * authentication, and when a client is freed. */
moduleNotifyUserChanged(client * c)5571 void moduleNotifyUserChanged(client *c) {
5572 if (c->auth_callback) {
5573 c->auth_callback(c->id, c->auth_callback_privdata);
5574
5575 /* The callback will fire exactly once, even if the user remains
5576 * the same. It is expected to completely clean up the state
5577 * so all references are cleared here. */
5578 c->auth_callback = NULL;
5579 c->auth_callback_privdata = NULL;
5580 c->auth_module = NULL;
5581 }
5582 }
5583
revokeClientAuthentication(client * c)5584 void revokeClientAuthentication(client *c) {
5585 /* Freeing the client would result in moduleNotifyUserChanged() to be
5586 * called later, however since we use revokeClientAuthentication() also
5587 * in moduleFreeAuthenticatedClients() to implement module unloading, we
5588 * do this action ASAP: this way if the module is unloaded, when the client
5589 * is eventually freed we don't rely on the module to still exist. */
5590 moduleNotifyUserChanged(c);
5591
5592 c->user = DefaultUser;
5593 c->authenticated = 0;
5594 /* We will write replies to this client later, so we can't close it
5595 * directly even if async. */
5596 if (c == server.current_client) {
5597 c->flags |= CLIENT_CLOSE_AFTER_COMMAND;
5598 } else {
5599 freeClientAsync(c);
5600 }
5601 }
5602
5603 /* Cleanup all clients that have been authenticated with this module. This
5604 * is called from onUnload() to give the module a chance to cleanup any
5605 * resources associated with clients it has authenticated. */
moduleFreeAuthenticatedClients(RedisModule * module)5606 static void moduleFreeAuthenticatedClients(RedisModule *module) {
5607 listIter li;
5608 listNode *ln;
5609 listRewind(server.clients,&li);
5610 while ((ln = listNext(&li)) != NULL) {
5611 client *c = listNodeValue(ln);
5612 if (!c->auth_module) continue;
5613
5614 RedisModule *auth_module = (RedisModule *) c->auth_module;
5615 if (auth_module == module) {
5616 revokeClientAuthentication(c);
5617 }
5618 }
5619 }
5620
5621 /* Creates a Redis ACL user that the module can use to authenticate a client.
5622 * After obtaining the user, the module should set what such user can do
5623 * using the RM_SetUserACL() function. Once configured, the user
5624 * can be used in order to authenticate a connection, with the specified
5625 * ACL rules, using the RedisModule_AuthClientWithUser() function.
5626 *
5627 * Note that:
5628 *
5629 * * Users created here are not listed by the ACL command.
5630 * * Users created here are not checked for duplicated name, so it's up to
5631 * the module calling this function to take care of not creating users
5632 * with the same name.
5633 * * The created user can be used to authenticate multiple Redis connections.
5634 *
5635 * The caller can later free the user using the function
5636 * RM_FreeModuleUser(). When this function is called, if there are
5637 * still clients authenticated with this user, they are disconnected.
5638 * The function to free the user should only be used when the caller really
5639 * wants to invalidate the user to define a new one with different
5640 * capabilities. */
RM_CreateModuleUser(const char * name)5641 RedisModuleUser *RM_CreateModuleUser(const char *name) {
5642 RedisModuleUser *new_user = zmalloc(sizeof(RedisModuleUser));
5643 new_user->user = ACLCreateUnlinkedUser();
5644
5645 /* Free the previous temporarily assigned name to assign the new one */
5646 sdsfree(new_user->user->name);
5647 new_user->user->name = sdsnew(name);
5648 return new_user;
5649 }
5650
5651 /* Frees a given user and disconnects all of the clients that have been
5652 * authenticated with it. See RM_CreateModuleUser for detailed usage.*/
RM_FreeModuleUser(RedisModuleUser * user)5653 int RM_FreeModuleUser(RedisModuleUser *user) {
5654 ACLFreeUserAndKillClients(user->user);
5655 zfree(user);
5656 return REDISMODULE_OK;
5657 }
5658
5659 /* Sets the permissions of a user created through the redis module
5660 * interface. The syntax is the same as ACL SETUSER, so refer to the
5661 * documentation in acl.c for more information. See RM_CreateModuleUser
5662 * for detailed usage.
5663 *
5664 * Returns REDISMODULE_OK on success and REDISMODULE_ERR on failure
5665 * and will set an errno describing why the operation failed. */
RM_SetModuleUserACL(RedisModuleUser * user,const char * acl)5666 int RM_SetModuleUserACL(RedisModuleUser *user, const char* acl) {
5667 return ACLSetUser(user->user, acl, -1);
5668 }
5669
5670 /* Authenticate the client associated with the context with
5671 * the provided user. Returns REDISMODULE_OK on success and
5672 * REDISMODULE_ERR on error.
5673 *
5674 * This authentication can be tracked with the optional callback and private
5675 * data fields. The callback will be called whenever the user of the client
5676 * changes. This callback should be used to cleanup any state that is being
5677 * kept in the module related to the client authentication. It will only be
5678 * called once, even when the user hasn't changed, in order to allow for a
5679 * new callback to be specified. If this authentication does not need to be
5680 * tracked, pass in NULL for the callback and privdata.
5681 *
5682 * If client_id is not NULL, it will be filled with the id of the client
5683 * that was authenticated. This can be used with the
5684 * RM_DeauthenticateAndCloseClient() API in order to deauthenticate a
5685 * previously authenticated client if the authentication is no longer valid.
5686 *
5687 * For expensive authentication operations, it is recommended to block the
5688 * client and do the authentication in the background and then attach the user
5689 * to the client in a threadsafe context. */
authenticateClientWithUser(RedisModuleCtx * ctx,user * user,RedisModuleUserChangedFunc callback,void * privdata,uint64_t * client_id)5690 static int authenticateClientWithUser(RedisModuleCtx *ctx, user *user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
5691 if (user->flags & USER_FLAG_DISABLED) {
5692 return REDISMODULE_ERR;
5693 }
5694
5695 /* Avoid settings which are meaningless and will be lost */
5696 if (!ctx->client || (ctx->client->flags & CLIENT_MODULE)) {
5697 return REDISMODULE_ERR;
5698 }
5699
5700 moduleNotifyUserChanged(ctx->client);
5701
5702 ctx->client->user = user;
5703 ctx->client->authenticated = 1;
5704
5705 if (callback) {
5706 ctx->client->auth_callback = callback;
5707 ctx->client->auth_callback_privdata = privdata;
5708 ctx->client->auth_module = ctx->module;
5709 }
5710
5711 if (client_id) {
5712 *client_id = ctx->client->id;
5713 }
5714
5715 return REDISMODULE_OK;
5716 }
5717
5718
5719 /* Authenticate the current context's user with the provided redis acl user.
5720 * Returns REDISMODULE_ERR if the user is disabled.
5721 *
5722 * See authenticateClientWithUser for information about callback, client_id,
5723 * and general usage for authentication. */
RM_AuthenticateClientWithUser(RedisModuleCtx * ctx,RedisModuleUser * module_user,RedisModuleUserChangedFunc callback,void * privdata,uint64_t * client_id)5724 int RM_AuthenticateClientWithUser(RedisModuleCtx *ctx, RedisModuleUser *module_user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
5725 return authenticateClientWithUser(ctx, module_user->user, callback, privdata, client_id);
5726 }
5727
5728 /* Authenticate the current context's user with the provided redis acl user.
5729 * Returns REDISMODULE_ERR if the user is disabled or the user does not exist.
5730 *
5731 * See authenticateClientWithUser for information about callback, client_id,
5732 * and general usage for authentication. */
RM_AuthenticateClientWithACLUser(RedisModuleCtx * ctx,const char * name,size_t len,RedisModuleUserChangedFunc callback,void * privdata,uint64_t * client_id)5733 int RM_AuthenticateClientWithACLUser(RedisModuleCtx *ctx, const char *name, size_t len, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
5734 user *acl_user = ACLGetUserByName(name, len);
5735
5736 if (!acl_user) {
5737 return REDISMODULE_ERR;
5738 }
5739 return authenticateClientWithUser(ctx, acl_user, callback, privdata, client_id);
5740 }
5741
5742 /* Deauthenticate and close the client. The client resources will not be
5743 * be immediately freed, but will be cleaned up in a background job. This is
5744 * the recommended way to deauthenicate a client since most clients can't
5745 * handle users becoming deauthenticated. Returns REDISMODULE_ERR when the
5746 * client doesn't exist and REDISMODULE_OK when the operation was successful.
5747 *
5748 * The client ID is returned from the RM_AuthenticateClientWithUser and
5749 * RM_AuthenticateClientWithACLUser APIs, but can be obtained through
5750 * the CLIENT api or through server events.
5751 *
5752 * This function is not thread safe, and must be executed within the context
5753 * of a command or thread safe context. */
RM_DeauthenticateAndCloseClient(RedisModuleCtx * ctx,uint64_t client_id)5754 int RM_DeauthenticateAndCloseClient(RedisModuleCtx *ctx, uint64_t client_id) {
5755 UNUSED(ctx);
5756 client *c = lookupClientByID(client_id);
5757 if (c == NULL) return REDISMODULE_ERR;
5758
5759 /* Revoke also marks client to be closed ASAP */
5760 revokeClientAuthentication(c);
5761 return REDISMODULE_OK;
5762 }
5763
5764 /* Return the X.509 client-side certificate used by the client to authenticate
5765 * this connection.
5766 *
5767 * The return value is an allocated RedisModuleString that is a X.509 certificate
5768 * encoded in PEM (Base64) format. It should be freed (or auto-freed) by the caller.
5769 *
5770 * A NULL value is returned in the following conditions:
5771 *
5772 * - Connection ID does not exist
5773 * - Connection is not a TLS connection
5774 * - Connection is a TLS connection but no client ceritifcate was used
5775 */
RM_GetClientCertificate(RedisModuleCtx * ctx,uint64_t client_id)5776 RedisModuleString *RM_GetClientCertificate(RedisModuleCtx *ctx, uint64_t client_id) {
5777 client *c = lookupClientByID(client_id);
5778 if (c == NULL) return NULL;
5779
5780 sds cert = connTLSGetPeerCert(c->conn);
5781 if (!cert) return NULL;
5782
5783 RedisModuleString *s = createObject(OBJ_STRING, cert);
5784 if (ctx != NULL) autoMemoryAdd(ctx, REDISMODULE_AM_STRING, s);
5785
5786 return s;
5787 }
5788
5789 /* --------------------------------------------------------------------------
5790 * Modules Dictionary API
5791 *
5792 * Implements a sorted dictionary (actually backed by a radix tree) with
5793 * the usual get / set / del / num-items API, together with an iterator
5794 * capable of going back and forth.
5795 * -------------------------------------------------------------------------- */
5796
5797 /* Create a new dictionary. The 'ctx' pointer can be the current module context
5798 * or NULL, depending on what you want. Please follow the following rules:
5799 *
5800 * 1. Use a NULL context if you plan to retain a reference to this dictionary
5801 * that will survive the time of the module callback where you created it.
5802 * 2. Use a NULL context if no context is available at the time you are creating
5803 * the dictionary (of course...).
5804 * 3. However use the current callback context as 'ctx' argument if the
5805 * dictionary time to live is just limited to the callback scope. In this
5806 * case, if enabled, you can enjoy the automatic memory management that will
5807 * reclaim the dictionary memory, as well as the strings returned by the
5808 * Next / Prev dictionary iterator calls.
5809 */
RM_CreateDict(RedisModuleCtx * ctx)5810 RedisModuleDict *RM_CreateDict(RedisModuleCtx *ctx) {
5811 struct RedisModuleDict *d = zmalloc(sizeof(*d));
5812 d->rax = raxNew();
5813 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_DICT,d);
5814 return d;
5815 }
5816
5817 /* Free a dictionary created with RM_CreateDict(). You need to pass the
5818 * context pointer 'ctx' only if the dictionary was created using the
5819 * context instead of passing NULL. */
RM_FreeDict(RedisModuleCtx * ctx,RedisModuleDict * d)5820 void RM_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d) {
5821 if (ctx != NULL) autoMemoryFreed(ctx,REDISMODULE_AM_DICT,d);
5822 raxFree(d->rax);
5823 zfree(d);
5824 }
5825
5826 /* Return the size of the dictionary (number of keys). */
RM_DictSize(RedisModuleDict * d)5827 uint64_t RM_DictSize(RedisModuleDict *d) {
5828 return raxSize(d->rax);
5829 }
5830
5831 /* Store the specified key into the dictionary, setting its value to the
5832 * pointer 'ptr'. If the key was added with success, since it did not
5833 * already exist, REDISMODULE_OK is returned. Otherwise if the key already
5834 * exists the function returns REDISMODULE_ERR. */
RM_DictSetC(RedisModuleDict * d,void * key,size_t keylen,void * ptr)5835 int RM_DictSetC(RedisModuleDict *d, void *key, size_t keylen, void *ptr) {
5836 int retval = raxTryInsert(d->rax,key,keylen,ptr,NULL);
5837 return (retval == 1) ? REDISMODULE_OK : REDISMODULE_ERR;
5838 }
5839
5840 /* Like RedisModule_DictSetC() but will replace the key with the new
5841 * value if the key already exists. */
RM_DictReplaceC(RedisModuleDict * d,void * key,size_t keylen,void * ptr)5842 int RM_DictReplaceC(RedisModuleDict *d, void *key, size_t keylen, void *ptr) {
5843 int retval = raxInsert(d->rax,key,keylen,ptr,NULL);
5844 return (retval == 1) ? REDISMODULE_OK : REDISMODULE_ERR;
5845 }
5846
5847 /* Like RedisModule_DictSetC() but takes the key as a RedisModuleString. */
RM_DictSet(RedisModuleDict * d,RedisModuleString * key,void * ptr)5848 int RM_DictSet(RedisModuleDict *d, RedisModuleString *key, void *ptr) {
5849 return RM_DictSetC(d,key->ptr,sdslen(key->ptr),ptr);
5850 }
5851
5852 /* Like RedisModule_DictReplaceC() but takes the key as a RedisModuleString. */
RM_DictReplace(RedisModuleDict * d,RedisModuleString * key,void * ptr)5853 int RM_DictReplace(RedisModuleDict *d, RedisModuleString *key, void *ptr) {
5854 return RM_DictReplaceC(d,key->ptr,sdslen(key->ptr),ptr);
5855 }
5856
5857 /* Return the value stored at the specified key. The function returns NULL
5858 * both in the case the key does not exist, or if you actually stored
5859 * NULL at key. So, optionally, if the 'nokey' pointer is not NULL, it will
5860 * be set by reference to 1 if the key does not exist, or to 0 if the key
5861 * exists. */
RM_DictGetC(RedisModuleDict * d,void * key,size_t keylen,int * nokey)5862 void *RM_DictGetC(RedisModuleDict *d, void *key, size_t keylen, int *nokey) {
5863 void *res = raxFind(d->rax,key,keylen);
5864 if (nokey) *nokey = (res == raxNotFound);
5865 return (res == raxNotFound) ? NULL : res;
5866 }
5867
5868 /* Like RedisModule_DictGetC() but takes the key as a RedisModuleString. */
RM_DictGet(RedisModuleDict * d,RedisModuleString * key,int * nokey)5869 void *RM_DictGet(RedisModuleDict *d, RedisModuleString *key, int *nokey) {
5870 return RM_DictGetC(d,key->ptr,sdslen(key->ptr),nokey);
5871 }
5872
5873 /* Remove the specified key from the dictionary, returning REDISMODULE_OK if
5874 * the key was found and delted, or REDISMODULE_ERR if instead there was
5875 * no such key in the dictionary. When the operation is successful, if
5876 * 'oldval' is not NULL, then '*oldval' is set to the value stored at the
5877 * key before it was deleted. Using this feature it is possible to get
5878 * a pointer to the value (for instance in order to release it), without
5879 * having to call RedisModule_DictGet() before deleting the key. */
RM_DictDelC(RedisModuleDict * d,void * key,size_t keylen,void * oldval)5880 int RM_DictDelC(RedisModuleDict *d, void *key, size_t keylen, void *oldval) {
5881 int retval = raxRemove(d->rax,key,keylen,oldval);
5882 return retval ? REDISMODULE_OK : REDISMODULE_ERR;
5883 }
5884
5885 /* Like RedisModule_DictDelC() but gets the key as a RedisModuleString. */
RM_DictDel(RedisModuleDict * d,RedisModuleString * key,void * oldval)5886 int RM_DictDel(RedisModuleDict *d, RedisModuleString *key, void *oldval) {
5887 return RM_DictDelC(d,key->ptr,sdslen(key->ptr),oldval);
5888 }
5889
5890 /* Return an iterator, setup in order to start iterating from the specified
5891 * key by applying the operator 'op', which is just a string specifying the
5892 * comparison operator to use in order to seek the first element. The
5893 * operators available are:
5894 *
5895 * "^" -- Seek the first (lexicographically smaller) key.
5896 * "$" -- Seek the last (lexicographically biffer) key.
5897 * ">" -- Seek the first element greater than the specified key.
5898 * ">=" -- Seek the first element greater or equal than the specified key.
5899 * "<" -- Seek the first element smaller than the specified key.
5900 * "<=" -- Seek the first element smaller or equal than the specified key.
5901 * "==" -- Seek the first element matching exactly the specified key.
5902 *
5903 * Note that for "^" and "$" the passed key is not used, and the user may
5904 * just pass NULL with a length of 0.
5905 *
5906 * If the element to start the iteration cannot be seeked based on the
5907 * key and operator passed, RedisModule_DictNext() / Prev() will just return
5908 * REDISMODULE_ERR at the first call, otherwise they'll produce elements.
5909 */
RM_DictIteratorStartC(RedisModuleDict * d,const char * op,void * key,size_t keylen)5910 RedisModuleDictIter *RM_DictIteratorStartC(RedisModuleDict *d, const char *op, void *key, size_t keylen) {
5911 RedisModuleDictIter *di = zmalloc(sizeof(*di));
5912 di->dict = d;
5913 raxStart(&di->ri,d->rax);
5914 raxSeek(&di->ri,op,key,keylen);
5915 return di;
5916 }
5917
5918 /* Exactly like RedisModule_DictIteratorStartC, but the key is passed as a
5919 * RedisModuleString. */
RM_DictIteratorStart(RedisModuleDict * d,const char * op,RedisModuleString * key)5920 RedisModuleDictIter *RM_DictIteratorStart(RedisModuleDict *d, const char *op, RedisModuleString *key) {
5921 return RM_DictIteratorStartC(d,op,key->ptr,sdslen(key->ptr));
5922 }
5923
5924 /* Release the iterator created with RedisModule_DictIteratorStart(). This call
5925 * is mandatory otherwise a memory leak is introduced in the module. */
RM_DictIteratorStop(RedisModuleDictIter * di)5926 void RM_DictIteratorStop(RedisModuleDictIter *di) {
5927 raxStop(&di->ri);
5928 zfree(di);
5929 }
5930
5931 /* After its creation with RedisModule_DictIteratorStart(), it is possible to
5932 * change the currently selected element of the iterator by using this
5933 * API call. The result based on the operator and key is exactly like
5934 * the function RedisModule_DictIteratorStart(), however in this case the
5935 * return value is just REDISMODULE_OK in case the seeked element was found,
5936 * or REDISMODULE_ERR in case it was not possible to seek the specified
5937 * element. It is possible to reseek an iterator as many times as you want. */
RM_DictIteratorReseekC(RedisModuleDictIter * di,const char * op,void * key,size_t keylen)5938 int RM_DictIteratorReseekC(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) {
5939 return raxSeek(&di->ri,op,key,keylen);
5940 }
5941
5942 /* Like RedisModule_DictIteratorReseekC() but takes the key as as a
5943 * RedisModuleString. */
RM_DictIteratorReseek(RedisModuleDictIter * di,const char * op,RedisModuleString * key)5944 int RM_DictIteratorReseek(RedisModuleDictIter *di, const char *op, RedisModuleString *key) {
5945 return RM_DictIteratorReseekC(di,op,key->ptr,sdslen(key->ptr));
5946 }
5947
5948 /* Return the current item of the dictionary iterator 'di' and steps to the
5949 * next element. If the iterator already yield the last element and there
5950 * are no other elements to return, NULL is returned, otherwise a pointer
5951 * to a string representing the key is provided, and the '*keylen' length
5952 * is set by reference (if keylen is not NULL). The '*dataptr', if not NULL
5953 * is set to the value of the pointer stored at the returned key as auxiliary
5954 * data (as set by the RedisModule_DictSet API).
5955 *
5956 * Usage example:
5957 *
5958 * ... create the iterator here ...
5959 * char *key;
5960 * void *data;
5961 * while((key = RedisModule_DictNextC(iter,&keylen,&data)) != NULL) {
5962 * printf("%.*s %p\n", (int)keylen, key, data);
5963 * }
5964 *
5965 * The returned pointer is of type void because sometimes it makes sense
5966 * to cast it to a char* sometimes to an unsigned char* depending on the
5967 * fact it contains or not binary data, so this API ends being more
5968 * comfortable to use.
5969 *
5970 * The validity of the returned pointer is until the next call to the
5971 * next/prev iterator step. Also the pointer is no longer valid once the
5972 * iterator is released. */
RM_DictNextC(RedisModuleDictIter * di,size_t * keylen,void ** dataptr)5973 void *RM_DictNextC(RedisModuleDictIter *di, size_t *keylen, void **dataptr) {
5974 if (!raxNext(&di->ri)) return NULL;
5975 if (keylen) *keylen = di->ri.key_len;
5976 if (dataptr) *dataptr = di->ri.data;
5977 return di->ri.key;
5978 }
5979
5980 /* This function is exactly like RedisModule_DictNext() but after returning
5981 * the currently selected element in the iterator, it selects the previous
5982 * element (laxicographically smaller) instead of the next one. */
RM_DictPrevC(RedisModuleDictIter * di,size_t * keylen,void ** dataptr)5983 void *RM_DictPrevC(RedisModuleDictIter *di, size_t *keylen, void **dataptr) {
5984 if (!raxPrev(&di->ri)) return NULL;
5985 if (keylen) *keylen = di->ri.key_len;
5986 if (dataptr) *dataptr = di->ri.data;
5987 return di->ri.key;
5988 }
5989
5990 /* Like RedisModuleNextC(), but instead of returning an internally allocated
5991 * buffer and key length, it returns directly a module string object allocated
5992 * in the specified context 'ctx' (that may be NULL exactly like for the main
5993 * API RedisModule_CreateString).
5994 *
5995 * The returned string object should be deallocated after use, either manually
5996 * or by using a context that has automatic memory management active. */
RM_DictNext(RedisModuleCtx * ctx,RedisModuleDictIter * di,void ** dataptr)5997 RedisModuleString *RM_DictNext(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr) {
5998 size_t keylen;
5999 void *key = RM_DictNextC(di,&keylen,dataptr);
6000 if (key == NULL) return NULL;
6001 return RM_CreateString(ctx,key,keylen);
6002 }
6003
6004 /* Like RedisModule_DictNext() but after returning the currently selected
6005 * element in the iterator, it selects the previous element (laxicographically
6006 * smaller) instead of the next one. */
RM_DictPrev(RedisModuleCtx * ctx,RedisModuleDictIter * di,void ** dataptr)6007 RedisModuleString *RM_DictPrev(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr) {
6008 size_t keylen;
6009 void *key = RM_DictPrevC(di,&keylen,dataptr);
6010 if (key == NULL) return NULL;
6011 return RM_CreateString(ctx,key,keylen);
6012 }
6013
6014 /* Compare the element currently pointed by the iterator to the specified
6015 * element given by key/keylen, according to the operator 'op' (the set of
6016 * valid operators are the same valid for RedisModule_DictIteratorStart).
6017 * If the comparision is successful the command returns REDISMODULE_OK
6018 * otherwise REDISMODULE_ERR is returned.
6019 *
6020 * This is useful when we want to just emit a lexicographical range, so
6021 * in the loop, as we iterate elements, we can also check if we are still
6022 * on range.
6023 *
6024 * The function return REDISMODULE_ERR if the iterator reached the
6025 * end of elements condition as well. */
RM_DictCompareC(RedisModuleDictIter * di,const char * op,void * key,size_t keylen)6026 int RM_DictCompareC(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) {
6027 if (raxEOF(&di->ri)) return REDISMODULE_ERR;
6028 int res = raxCompare(&di->ri,op,key,keylen);
6029 return res ? REDISMODULE_OK : REDISMODULE_ERR;
6030 }
6031
6032 /* Like RedisModule_DictCompareC but gets the key to compare with the current
6033 * iterator key as a RedisModuleString. */
RM_DictCompare(RedisModuleDictIter * di,const char * op,RedisModuleString * key)6034 int RM_DictCompare(RedisModuleDictIter *di, const char *op, RedisModuleString *key) {
6035 if (raxEOF(&di->ri)) return REDISMODULE_ERR;
6036 int res = raxCompare(&di->ri,op,key->ptr,sdslen(key->ptr));
6037 return res ? REDISMODULE_OK : REDISMODULE_ERR;
6038 }
6039
6040
6041
6042
6043 /* --------------------------------------------------------------------------
6044 * Modules Info fields
6045 * -------------------------------------------------------------------------- */
6046
6047 int RM_InfoEndDictField(RedisModuleInfoCtx *ctx);
6048
6049 /* Used to start a new section, before adding any fields. the section name will
6050 * be prefixed by "<modulename>_" and must only include A-Z,a-z,0-9.
6051 * NULL or empty string indicates the default section (only <modulename>) is used.
6052 * When return value is REDISMODULE_ERR, the section should and will be skipped. */
RM_InfoAddSection(RedisModuleInfoCtx * ctx,char * name)6053 int RM_InfoAddSection(RedisModuleInfoCtx *ctx, char *name) {
6054 sds full_name = sdsdup(ctx->module->name);
6055 if (name != NULL && strlen(name) > 0)
6056 full_name = sdscatfmt(full_name, "_%s", name);
6057
6058 /* Implicitly end dicts, instead of returning an error which is likely un checked. */
6059 if (ctx->in_dict_field)
6060 RM_InfoEndDictField(ctx);
6061
6062 /* proceed only if:
6063 * 1) no section was requested (emit all)
6064 * 2) the module name was requested (emit all)
6065 * 3) this specific section was requested. */
6066 if (ctx->requested_section) {
6067 if (strcasecmp(ctx->requested_section, full_name) &&
6068 strcasecmp(ctx->requested_section, ctx->module->name)) {
6069 sdsfree(full_name);
6070 ctx->in_section = 0;
6071 return REDISMODULE_ERR;
6072 }
6073 }
6074 if (ctx->sections++) ctx->info = sdscat(ctx->info,"\r\n");
6075 ctx->info = sdscatfmt(ctx->info, "# %S\r\n", full_name);
6076 ctx->in_section = 1;
6077 sdsfree(full_name);
6078 return REDISMODULE_OK;
6079 }
6080
6081 /* Starts a dict field, similar to the ones in INFO KEYSPACE. Use normal
6082 * RedisModule_InfoAddField* functions to add the items to this field, and
6083 * terminate with RedisModule_InfoEndDictField. */
RM_InfoBeginDictField(RedisModuleInfoCtx * ctx,char * name)6084 int RM_InfoBeginDictField(RedisModuleInfoCtx *ctx, char *name) {
6085 if (!ctx->in_section)
6086 return REDISMODULE_ERR;
6087 /* Implicitly end dicts, instead of returning an error which is likely un checked. */
6088 if (ctx->in_dict_field)
6089 RM_InfoEndDictField(ctx);
6090 ctx->info = sdscatfmt(ctx->info,
6091 "%s_%s:",
6092 ctx->module->name,
6093 name);
6094 ctx->in_dict_field = 1;
6095 return REDISMODULE_OK;
6096 }
6097
6098 /* Ends a dict field, see RedisModule_InfoBeginDictField */
RM_InfoEndDictField(RedisModuleInfoCtx * ctx)6099 int RM_InfoEndDictField(RedisModuleInfoCtx *ctx) {
6100 if (!ctx->in_dict_field)
6101 return REDISMODULE_ERR;
6102 /* trim the last ',' if found. */
6103 if (ctx->info[sdslen(ctx->info)-1]==',')
6104 sdsIncrLen(ctx->info, -1);
6105 ctx->info = sdscat(ctx->info, "\r\n");
6106 ctx->in_dict_field = 0;
6107 return REDISMODULE_OK;
6108 }
6109
6110 /* Used by RedisModuleInfoFunc to add info fields.
6111 * Each field will be automatically prefixed by "<modulename>_".
6112 * Field names or values must not include \r\n of ":" */
RM_InfoAddFieldString(RedisModuleInfoCtx * ctx,char * field,RedisModuleString * value)6113 int RM_InfoAddFieldString(RedisModuleInfoCtx *ctx, char *field, RedisModuleString *value) {
6114 if (!ctx->in_section)
6115 return REDISMODULE_ERR;
6116 if (ctx->in_dict_field) {
6117 ctx->info = sdscatfmt(ctx->info,
6118 "%s=%S,",
6119 field,
6120 (sds)value->ptr);
6121 return REDISMODULE_OK;
6122 }
6123 ctx->info = sdscatfmt(ctx->info,
6124 "%s_%s:%S\r\n",
6125 ctx->module->name,
6126 field,
6127 (sds)value->ptr);
6128 return REDISMODULE_OK;
6129 }
6130
RM_InfoAddFieldCString(RedisModuleInfoCtx * ctx,char * field,char * value)6131 int RM_InfoAddFieldCString(RedisModuleInfoCtx *ctx, char *field, char *value) {
6132 if (!ctx->in_section)
6133 return REDISMODULE_ERR;
6134 if (ctx->in_dict_field) {
6135 ctx->info = sdscatfmt(ctx->info,
6136 "%s=%s,",
6137 field,
6138 value);
6139 return REDISMODULE_OK;
6140 }
6141 ctx->info = sdscatfmt(ctx->info,
6142 "%s_%s:%s\r\n",
6143 ctx->module->name,
6144 field,
6145 value);
6146 return REDISMODULE_OK;
6147 }
6148
RM_InfoAddFieldDouble(RedisModuleInfoCtx * ctx,char * field,double value)6149 int RM_InfoAddFieldDouble(RedisModuleInfoCtx *ctx, char *field, double value) {
6150 if (!ctx->in_section)
6151 return REDISMODULE_ERR;
6152 if (ctx->in_dict_field) {
6153 ctx->info = sdscatprintf(ctx->info,
6154 "%s=%.17g,",
6155 field,
6156 value);
6157 return REDISMODULE_OK;
6158 }
6159 ctx->info = sdscatprintf(ctx->info,
6160 "%s_%s:%.17g\r\n",
6161 ctx->module->name,
6162 field,
6163 value);
6164 return REDISMODULE_OK;
6165 }
6166
RM_InfoAddFieldLongLong(RedisModuleInfoCtx * ctx,char * field,long long value)6167 int RM_InfoAddFieldLongLong(RedisModuleInfoCtx *ctx, char *field, long long value) {
6168 if (!ctx->in_section)
6169 return REDISMODULE_ERR;
6170 if (ctx->in_dict_field) {
6171 ctx->info = sdscatfmt(ctx->info,
6172 "%s=%I,",
6173 field,
6174 value);
6175 return REDISMODULE_OK;
6176 }
6177 ctx->info = sdscatfmt(ctx->info,
6178 "%s_%s:%I\r\n",
6179 ctx->module->name,
6180 field,
6181 value);
6182 return REDISMODULE_OK;
6183 }
6184
RM_InfoAddFieldULongLong(RedisModuleInfoCtx * ctx,char * field,unsigned long long value)6185 int RM_InfoAddFieldULongLong(RedisModuleInfoCtx *ctx, char *field, unsigned long long value) {
6186 if (!ctx->in_section)
6187 return REDISMODULE_ERR;
6188 if (ctx->in_dict_field) {
6189 ctx->info = sdscatfmt(ctx->info,
6190 "%s=%U,",
6191 field,
6192 value);
6193 return REDISMODULE_OK;
6194 }
6195 ctx->info = sdscatfmt(ctx->info,
6196 "%s_%s:%U\r\n",
6197 ctx->module->name,
6198 field,
6199 value);
6200 return REDISMODULE_OK;
6201 }
6202
RM_RegisterInfoFunc(RedisModuleCtx * ctx,RedisModuleInfoFunc cb)6203 int RM_RegisterInfoFunc(RedisModuleCtx *ctx, RedisModuleInfoFunc cb) {
6204 ctx->module->info_cb = cb;
6205 return REDISMODULE_OK;
6206 }
6207
modulesCollectInfo(sds info,const char * section,int for_crash_report,int sections)6208 sds modulesCollectInfo(sds info, const char *section, int for_crash_report, int sections) {
6209 dictIterator *di = dictGetIterator(modules);
6210 dictEntry *de;
6211
6212 while ((de = dictNext(di)) != NULL) {
6213 struct RedisModule *module = dictGetVal(de);
6214 if (!module->info_cb)
6215 continue;
6216 RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0, 0};
6217 module->info_cb(&info_ctx, for_crash_report);
6218 /* Implicitly end dicts (no way to handle errors, and we must add the newline). */
6219 if (info_ctx.in_dict_field)
6220 RM_InfoEndDictField(&info_ctx);
6221 info = info_ctx.info;
6222 sections = info_ctx.sections;
6223 }
6224 dictReleaseIterator(di);
6225 return info;
6226 }
6227
6228 /* Get information about the server similar to the one that returns from the
6229 * INFO command. This function takes an optional 'section' argument that may
6230 * be NULL. The return value holds the output and can be used with
6231 * RedisModule_ServerInfoGetField and alike to get the individual fields.
6232 * When done, it needs to be freed with RedisModule_FreeServerInfo or with the
6233 * automatic memory management mechanism if enabled. */
RM_GetServerInfo(RedisModuleCtx * ctx,const char * section)6234 RedisModuleServerInfoData *RM_GetServerInfo(RedisModuleCtx *ctx, const char *section) {
6235 struct RedisModuleServerInfoData *d = zmalloc(sizeof(*d));
6236 d->rax = raxNew();
6237 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_INFO,d);
6238 sds info = genRedisInfoString(section);
6239 int totlines, i;
6240 sds *lines = sdssplitlen(info, sdslen(info), "\r\n", 2, &totlines);
6241 for(i=0; i<totlines; i++) {
6242 sds line = lines[i];
6243 if (line[0]=='#') continue;
6244 char *sep = strchr(line, ':');
6245 if (!sep) continue;
6246 unsigned char *key = (unsigned char*)line;
6247 size_t keylen = (intptr_t)sep-(intptr_t)line;
6248 sds val = sdsnewlen(sep+1,sdslen(line)-((intptr_t)sep-(intptr_t)line)-1);
6249 if (!raxTryInsert(d->rax,key,keylen,val,NULL))
6250 sdsfree(val);
6251 }
6252 sdsfree(info);
6253 sdsfreesplitres(lines,totlines);
6254 return d;
6255 }
6256
6257 /* Free data created with RM_GetServerInfo(). You need to pass the
6258 * context pointer 'ctx' only if the dictionary was created using the
6259 * context instead of passing NULL. */
RM_FreeServerInfo(RedisModuleCtx * ctx,RedisModuleServerInfoData * data)6260 void RM_FreeServerInfo(RedisModuleCtx *ctx, RedisModuleServerInfoData *data) {
6261 if (ctx != NULL) autoMemoryFreed(ctx,REDISMODULE_AM_INFO,data);
6262 raxIterator ri;
6263 raxStart(&ri,data->rax);
6264 while(1) {
6265 raxSeek(&ri,"^",NULL,0);
6266 if (!raxNext(&ri)) break;
6267 raxRemove(data->rax,(unsigned char*)ri.key,ri.key_len,NULL);
6268 sdsfree(ri.data);
6269 }
6270 raxStop(&ri);
6271 raxFree(data->rax);
6272 zfree(data);
6273 }
6274
6275 /* Get the value of a field from data collected with RM_GetServerInfo(). You
6276 * need to pass the context pointer 'ctx' only if you want to use auto memory
6277 * mechanism to release the returned string. Return value will be NULL if the
6278 * field was not found. */
RM_ServerInfoGetField(RedisModuleCtx * ctx,RedisModuleServerInfoData * data,const char * field)6279 RedisModuleString *RM_ServerInfoGetField(RedisModuleCtx *ctx, RedisModuleServerInfoData *data, const char* field) {
6280 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
6281 if (val == raxNotFound) return NULL;
6282 RedisModuleString *o = createStringObject(val,sdslen(val));
6283 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
6284 return o;
6285 }
6286
6287 /* Similar to RM_ServerInfoGetField, but returns a char* which should not be freed but the caller. */
RM_ServerInfoGetFieldC(RedisModuleServerInfoData * data,const char * field)6288 const char *RM_ServerInfoGetFieldC(RedisModuleServerInfoData *data, const char* field) {
6289 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
6290 if (val == raxNotFound) return NULL;
6291 return val;
6292 }
6293
6294 /* Get the value of a field from data collected with RM_GetServerInfo(). If the
6295 * field is not found, or is not numerical or out of range, return value will be
6296 * 0, and the optional out_err argument will be set to REDISMODULE_ERR. */
RM_ServerInfoGetFieldSigned(RedisModuleServerInfoData * data,const char * field,int * out_err)6297 long long RM_ServerInfoGetFieldSigned(RedisModuleServerInfoData *data, const char* field, int *out_err) {
6298 long long ll;
6299 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
6300 if (val == raxNotFound) {
6301 if (out_err) *out_err = REDISMODULE_ERR;
6302 return 0;
6303 }
6304 if (!string2ll(val,sdslen(val),&ll)) {
6305 if (out_err) *out_err = REDISMODULE_ERR;
6306 return 0;
6307 }
6308 if (out_err) *out_err = REDISMODULE_OK;
6309 return ll;
6310 }
6311
6312 /* Get the value of a field from data collected with RM_GetServerInfo(). If the
6313 * field is not found, or is not numerical or out of range, return value will be
6314 * 0, and the optional out_err argument will be set to REDISMODULE_ERR. */
RM_ServerInfoGetFieldUnsigned(RedisModuleServerInfoData * data,const char * field,int * out_err)6315 unsigned long long RM_ServerInfoGetFieldUnsigned(RedisModuleServerInfoData *data, const char* field, int *out_err) {
6316 unsigned long long ll;
6317 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
6318 if (val == raxNotFound) {
6319 if (out_err) *out_err = REDISMODULE_ERR;
6320 return 0;
6321 }
6322 if (!string2ull(val,&ll)) {
6323 if (out_err) *out_err = REDISMODULE_ERR;
6324 return 0;
6325 }
6326 if (out_err) *out_err = REDISMODULE_OK;
6327 return ll;
6328 }
6329
6330 /* Get the value of a field from data collected with RM_GetServerInfo(). If the
6331 * field is not found, or is not a double, return value will be 0, and the
6332 * optional out_err argument will be set to REDISMODULE_ERR. */
RM_ServerInfoGetFieldDouble(RedisModuleServerInfoData * data,const char * field,int * out_err)6333 double RM_ServerInfoGetFieldDouble(RedisModuleServerInfoData *data, const char* field, int *out_err) {
6334 double dbl;
6335 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
6336 if (val == raxNotFound) {
6337 if (out_err) *out_err = REDISMODULE_ERR;
6338 return 0;
6339 }
6340 if (!string2d(val,sdslen(val),&dbl)) {
6341 if (out_err) *out_err = REDISMODULE_ERR;
6342 return 0;
6343 }
6344 if (out_err) *out_err = REDISMODULE_OK;
6345 return dbl;
6346 }
6347
6348 /* --------------------------------------------------------------------------
6349 * Modules utility APIs
6350 * -------------------------------------------------------------------------- */
6351
6352 /* Return random bytes using SHA1 in counter mode with a /dev/urandom
6353 * initialized seed. This function is fast so can be used to generate
6354 * many bytes without any effect on the operating system entropy pool.
6355 * Currently this function is not thread safe. */
RM_GetRandomBytes(unsigned char * dst,size_t len)6356 void RM_GetRandomBytes(unsigned char *dst, size_t len) {
6357 getRandomBytes(dst,len);
6358 }
6359
6360 /* Like RedisModule_GetRandomBytes() but instead of setting the string to
6361 * random bytes the string is set to random characters in the in the
6362 * hex charset [0-9a-f]. */
RM_GetRandomHexChars(char * dst,size_t len)6363 void RM_GetRandomHexChars(char *dst, size_t len) {
6364 getRandomHexChars(dst,len);
6365 }
6366
6367 /* --------------------------------------------------------------------------
6368 * Modules API exporting / importing
6369 * -------------------------------------------------------------------------- */
6370
6371 /* This function is called by a module in order to export some API with a
6372 * given name. Other modules will be able to use this API by calling the
6373 * symmetrical function RM_GetSharedAPI() and casting the return value to
6374 * the right function pointer.
6375 *
6376 * The function will return REDISMODULE_OK if the name is not already taken,
6377 * otherwise REDISMODULE_ERR will be returned and no operation will be
6378 * performed.
6379 *
6380 * IMPORTANT: the apiname argument should be a string literal with static
6381 * lifetime. The API relies on the fact that it will always be valid in
6382 * the future. */
RM_ExportSharedAPI(RedisModuleCtx * ctx,const char * apiname,void * func)6383 int RM_ExportSharedAPI(RedisModuleCtx *ctx, const char *apiname, void *func) {
6384 RedisModuleSharedAPI *sapi = zmalloc(sizeof(*sapi));
6385 sapi->module = ctx->module;
6386 sapi->func = func;
6387 if (dictAdd(server.sharedapi, (char*)apiname, sapi) != DICT_OK) {
6388 zfree(sapi);
6389 return REDISMODULE_ERR;
6390 }
6391 return REDISMODULE_OK;
6392 }
6393
6394 /* Request an exported API pointer. The return value is just a void pointer
6395 * that the caller of this function will be required to cast to the right
6396 * function pointer, so this is a private contract between modules.
6397 *
6398 * If the requested API is not available then NULL is returned. Because
6399 * modules can be loaded at different times with different order, this
6400 * function calls should be put inside some module generic API registering
6401 * step, that is called every time a module attempts to execute a
6402 * command that requires external APIs: if some API cannot be resolved, the
6403 * command should return an error.
6404 *
6405 * Here is an example:
6406 *
6407 * int ... myCommandImplementation() {
6408 * if (getExternalAPIs() == 0) {
6409 * reply with an error here if we cannot have the APIs
6410 * }
6411 * // Use the API:
6412 * myFunctionPointer(foo);
6413 * }
6414 *
6415 * And the function registerAPI() is:
6416 *
6417 * int getExternalAPIs(void) {
6418 * static int api_loaded = 0;
6419 * if (api_loaded != 0) return 1; // APIs already resolved.
6420 *
6421 * myFunctionPointer = RedisModule_GetOtherModuleAPI("...");
6422 * if (myFunctionPointer == NULL) return 0;
6423 *
6424 * return 1;
6425 * }
6426 */
RM_GetSharedAPI(RedisModuleCtx * ctx,const char * apiname)6427 void *RM_GetSharedAPI(RedisModuleCtx *ctx, const char *apiname) {
6428 dictEntry *de = dictFind(server.sharedapi, apiname);
6429 if (de == NULL) return NULL;
6430 RedisModuleSharedAPI *sapi = dictGetVal(de);
6431 if (listSearchKey(sapi->module->usedby,ctx->module) == NULL) {
6432 listAddNodeTail(sapi->module->usedby,ctx->module);
6433 listAddNodeTail(ctx->module->using,sapi->module);
6434 }
6435 return sapi->func;
6436 }
6437
6438 /* Remove all the APIs registered by the specified module. Usually you
6439 * want this when the module is going to be unloaded. This function
6440 * assumes that's caller responsibility to make sure the APIs are not
6441 * used by other modules.
6442 *
6443 * The number of unregistered APIs is returned. */
moduleUnregisterSharedAPI(RedisModule * module)6444 int moduleUnregisterSharedAPI(RedisModule *module) {
6445 int count = 0;
6446 dictIterator *di = dictGetSafeIterator(server.sharedapi);
6447 dictEntry *de;
6448 while ((de = dictNext(di)) != NULL) {
6449 const char *apiname = dictGetKey(de);
6450 RedisModuleSharedAPI *sapi = dictGetVal(de);
6451 if (sapi->module == module) {
6452 dictDelete(server.sharedapi,apiname);
6453 zfree(sapi);
6454 count++;
6455 }
6456 }
6457 dictReleaseIterator(di);
6458 return count;
6459 }
6460
6461 /* Remove the specified module as an user of APIs of ever other module.
6462 * This is usually called when a module is unloaded.
6463 *
6464 * Returns the number of modules this module was using APIs from. */
moduleUnregisterUsedAPI(RedisModule * module)6465 int moduleUnregisterUsedAPI(RedisModule *module) {
6466 listIter li;
6467 listNode *ln;
6468 int count = 0;
6469
6470 listRewind(module->using,&li);
6471 while((ln = listNext(&li))) {
6472 RedisModule *used = ln->value;
6473 listNode *ln = listSearchKey(used->usedby,module);
6474 if (ln) {
6475 listDelNode(used->usedby,ln);
6476 count++;
6477 }
6478 }
6479 return count;
6480 }
6481
6482 /* Unregister all filters registered by a module.
6483 * This is called when a module is being unloaded.
6484 *
6485 * Returns the number of filters unregistered. */
moduleUnregisterFilters(RedisModule * module)6486 int moduleUnregisterFilters(RedisModule *module) {
6487 listIter li;
6488 listNode *ln;
6489 int count = 0;
6490
6491 listRewind(module->filters,&li);
6492 while((ln = listNext(&li))) {
6493 RedisModuleCommandFilter *filter = ln->value;
6494 listNode *ln = listSearchKey(moduleCommandFilters,filter);
6495 if (ln) {
6496 listDelNode(moduleCommandFilters,ln);
6497 count++;
6498 }
6499 zfree(filter);
6500 }
6501 return count;
6502 }
6503
6504 /* --------------------------------------------------------------------------
6505 * Module Command Filter API
6506 * -------------------------------------------------------------------------- */
6507
6508 /* Register a new command filter function.
6509 *
6510 * Command filtering makes it possible for modules to extend Redis by plugging
6511 * into the execution flow of all commands.
6512 *
6513 * A registered filter gets called before Redis executes *any* command. This
6514 * includes both core Redis commands and commands registered by any module. The
6515 * filter applies in all execution paths including:
6516 *
6517 * 1. Invocation by a client.
6518 * 2. Invocation through `RedisModule_Call()` by any module.
6519 * 3. Invocation through Lua 'redis.call()`.
6520 * 4. Replication of a command from a master.
6521 *
6522 * The filter executes in a special filter context, which is different and more
6523 * limited than a RedisModuleCtx. Because the filter affects any command, it
6524 * must be implemented in a very efficient way to reduce the performance impact
6525 * on Redis. All Redis Module API calls that require a valid context (such as
6526 * `RedisModule_Call()`, `RedisModule_OpenKey()`, etc.) are not supported in a
6527 * filter context.
6528 *
6529 * The `RedisModuleCommandFilterCtx` can be used to inspect or modify the
6530 * executed command and its arguments. As the filter executes before Redis
6531 * begins processing the command, any change will affect the way the command is
6532 * processed. For example, a module can override Redis commands this way:
6533 *
6534 * 1. Register a `MODULE.SET` command which implements an extended version of
6535 * the Redis `SET` command.
6536 * 2. Register a command filter which detects invocation of `SET` on a specific
6537 * pattern of keys. Once detected, the filter will replace the first
6538 * argument from `SET` to `MODULE.SET`.
6539 * 3. When filter execution is complete, Redis considers the new command name
6540 * and therefore executes the module's own command.
6541 *
6542 * Note that in the above use case, if `MODULE.SET` itself uses
6543 * `RedisModule_Call()` the filter will be applied on that call as well. If
6544 * that is not desired, the `REDISMODULE_CMDFILTER_NOSELF` flag can be set when
6545 * registering the filter.
6546 *
6547 * The `REDISMODULE_CMDFILTER_NOSELF` flag prevents execution flows that
6548 * originate from the module's own `RM_Call()` from reaching the filter. This
6549 * flag is effective for all execution flows, including nested ones, as long as
6550 * the execution begins from the module's command context or a thread-safe
6551 * context that is associated with a blocking command.
6552 *
6553 * Detached thread-safe contexts are *not* associated with the module and cannot
6554 * be protected by this flag.
6555 *
6556 * If multiple filters are registered (by the same or different modules), they
6557 * are executed in the order of registration.
6558 */
6559
RM_RegisterCommandFilter(RedisModuleCtx * ctx,RedisModuleCommandFilterFunc callback,int flags)6560 RedisModuleCommandFilter *RM_RegisterCommandFilter(RedisModuleCtx *ctx, RedisModuleCommandFilterFunc callback, int flags) {
6561 RedisModuleCommandFilter *filter = zmalloc(sizeof(*filter));
6562 filter->module = ctx->module;
6563 filter->callback = callback;
6564 filter->flags = flags;
6565
6566 listAddNodeTail(moduleCommandFilters, filter);
6567 listAddNodeTail(ctx->module->filters, filter);
6568 return filter;
6569 }
6570
6571 /* Unregister a command filter.
6572 */
RM_UnregisterCommandFilter(RedisModuleCtx * ctx,RedisModuleCommandFilter * filter)6573 int RM_UnregisterCommandFilter(RedisModuleCtx *ctx, RedisModuleCommandFilter *filter) {
6574 listNode *ln;
6575
6576 /* A module can only remove its own filters */
6577 if (filter->module != ctx->module) return REDISMODULE_ERR;
6578
6579 ln = listSearchKey(moduleCommandFilters,filter);
6580 if (!ln) return REDISMODULE_ERR;
6581 listDelNode(moduleCommandFilters,ln);
6582
6583 ln = listSearchKey(ctx->module->filters,filter);
6584 if (!ln) return REDISMODULE_ERR; /* Shouldn't happen */
6585 listDelNode(ctx->module->filters,ln);
6586
6587 zfree(filter);
6588
6589 return REDISMODULE_OK;
6590 }
6591
moduleCallCommandFilters(client * c)6592 void moduleCallCommandFilters(client *c) {
6593 if (listLength(moduleCommandFilters) == 0) return;
6594
6595 listIter li;
6596 listNode *ln;
6597 listRewind(moduleCommandFilters,&li);
6598
6599 RedisModuleCommandFilterCtx filter = {
6600 .argv = c->argv,
6601 .argc = c->argc
6602 };
6603
6604 while((ln = listNext(&li))) {
6605 RedisModuleCommandFilter *f = ln->value;
6606
6607 /* Skip filter if REDISMODULE_CMDFILTER_NOSELF is set and module is
6608 * currently processing a command.
6609 */
6610 if ((f->flags & REDISMODULE_CMDFILTER_NOSELF) && f->module->in_call) continue;
6611
6612 /* Call filter */
6613 f->callback(&filter);
6614 }
6615
6616 c->argv = filter.argv;
6617 c->argc = filter.argc;
6618 }
6619
6620 /* Return the number of arguments a filtered command has. The number of
6621 * arguments include the command itself.
6622 */
RM_CommandFilterArgsCount(RedisModuleCommandFilterCtx * fctx)6623 int RM_CommandFilterArgsCount(RedisModuleCommandFilterCtx *fctx)
6624 {
6625 return fctx->argc;
6626 }
6627
6628 /* Return the specified command argument. The first argument (position 0) is
6629 * the command itself, and the rest are user-provided args.
6630 */
RM_CommandFilterArgGet(RedisModuleCommandFilterCtx * fctx,int pos)6631 const RedisModuleString *RM_CommandFilterArgGet(RedisModuleCommandFilterCtx *fctx, int pos)
6632 {
6633 if (pos < 0 || pos >= fctx->argc) return NULL;
6634 return fctx->argv[pos];
6635 }
6636
6637 /* Modify the filtered command by inserting a new argument at the specified
6638 * position. The specified RedisModuleString argument may be used by Redis
6639 * after the filter context is destroyed, so it must not be auto-memory
6640 * allocated, freed or used elsewhere.
6641 */
6642
RM_CommandFilterArgInsert(RedisModuleCommandFilterCtx * fctx,int pos,RedisModuleString * arg)6643 int RM_CommandFilterArgInsert(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg)
6644 {
6645 int i;
6646
6647 if (pos < 0 || pos > fctx->argc) return REDISMODULE_ERR;
6648
6649 fctx->argv = zrealloc(fctx->argv, (fctx->argc+1)*sizeof(RedisModuleString *));
6650 for (i = fctx->argc; i > pos; i--) {
6651 fctx->argv[i] = fctx->argv[i-1];
6652 }
6653 fctx->argv[pos] = arg;
6654 fctx->argc++;
6655
6656 return REDISMODULE_OK;
6657 }
6658
6659 /* Modify the filtered command by replacing an existing argument with a new one.
6660 * The specified RedisModuleString argument may be used by Redis after the
6661 * filter context is destroyed, so it must not be auto-memory allocated, freed
6662 * or used elsewhere.
6663 */
6664
RM_CommandFilterArgReplace(RedisModuleCommandFilterCtx * fctx,int pos,RedisModuleString * arg)6665 int RM_CommandFilterArgReplace(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg)
6666 {
6667 if (pos < 0 || pos >= fctx->argc) return REDISMODULE_ERR;
6668
6669 decrRefCount(fctx->argv[pos]);
6670 fctx->argv[pos] = arg;
6671
6672 return REDISMODULE_OK;
6673 }
6674
6675 /* Modify the filtered command by deleting an argument at the specified
6676 * position.
6677 */
RM_CommandFilterArgDelete(RedisModuleCommandFilterCtx * fctx,int pos)6678 int RM_CommandFilterArgDelete(RedisModuleCommandFilterCtx *fctx, int pos)
6679 {
6680 int i;
6681 if (pos < 0 || pos >= fctx->argc) return REDISMODULE_ERR;
6682
6683 decrRefCount(fctx->argv[pos]);
6684 for (i = pos; i < fctx->argc-1; i++) {
6685 fctx->argv[i] = fctx->argv[i+1];
6686 }
6687 fctx->argc--;
6688
6689 return REDISMODULE_OK;
6690 }
6691
6692 /* For a given pointer allocated via RedisModule_Alloc() or
6693 * RedisModule_Realloc(), return the amount of memory allocated for it.
6694 * Note that this may be different (larger) than the memory we allocated
6695 * with the allocation calls, since sometimes the underlying allocator
6696 * will allocate more memory.
6697 */
RM_MallocSize(void * ptr)6698 size_t RM_MallocSize(void* ptr){
6699 return zmalloc_size(ptr);
6700 }
6701
6702 /* Return the a number between 0 to 1 indicating the amount of memory
6703 * currently used, relative to the Redis "maxmemory" configuration.
6704 *
6705 * 0 - No memory limit configured.
6706 * Between 0 and 1 - The percentage of the memory used normalized in 0-1 range.
6707 * Exactly 1 - Memory limit reached.
6708 * Greater 1 - More memory used than the configured limit.
6709 */
RM_GetUsedMemoryRatio()6710 float RM_GetUsedMemoryRatio(){
6711 float level;
6712 getMaxmemoryState(NULL, NULL, NULL, &level);
6713 return level;
6714 }
6715
6716 /* --------------------------------------------------------------------------
6717 * Scanning keyspace and hashes
6718 * -------------------------------------------------------------------------- */
6719
6720 typedef void (*RedisModuleScanCB)(RedisModuleCtx *ctx, RedisModuleString *keyname, RedisModuleKey *key, void *privdata);
6721 typedef struct {
6722 RedisModuleCtx *ctx;
6723 void* user_data;
6724 RedisModuleScanCB fn;
6725 } ScanCBData;
6726
6727 typedef struct RedisModuleScanCursor{
6728 int cursor;
6729 int done;
6730 }RedisModuleScanCursor;
6731
moduleScanCallback(void * privdata,const dictEntry * de)6732 static void moduleScanCallback(void *privdata, const dictEntry *de) {
6733 ScanCBData *data = privdata;
6734 sds key = dictGetKey(de);
6735 robj* val = dictGetVal(de);
6736 RedisModuleString *keyname = createObject(OBJ_STRING,sdsdup(key));
6737
6738 /* Setup the key handle. */
6739 RedisModuleKey kp = {0};
6740 moduleInitKey(&kp, data->ctx, keyname, val, REDISMODULE_READ);
6741
6742 data->fn(data->ctx, keyname, &kp, data->user_data);
6743
6744 moduleCloseKey(&kp);
6745 decrRefCount(keyname);
6746 }
6747
6748 /* Create a new cursor to be used with RedisModule_Scan */
RM_ScanCursorCreate()6749 RedisModuleScanCursor *RM_ScanCursorCreate() {
6750 RedisModuleScanCursor* cursor = zmalloc(sizeof(*cursor));
6751 cursor->cursor = 0;
6752 cursor->done = 0;
6753 return cursor;
6754 }
6755
6756 /* Restart an existing cursor. The keys will be rescanned. */
RM_ScanCursorRestart(RedisModuleScanCursor * cursor)6757 void RM_ScanCursorRestart(RedisModuleScanCursor *cursor) {
6758 cursor->cursor = 0;
6759 cursor->done = 0;
6760 }
6761
6762 /* Destroy the cursor struct. */
RM_ScanCursorDestroy(RedisModuleScanCursor * cursor)6763 void RM_ScanCursorDestroy(RedisModuleScanCursor *cursor) {
6764 zfree(cursor);
6765 }
6766
6767 /* Scan API that allows a module to scan all the keys and value in
6768 * the selected db.
6769 *
6770 * Callback for scan implementation.
6771 * void scan_callback(RedisModuleCtx *ctx, RedisModuleString *keyname,
6772 * RedisModuleKey *key, void *privdata);
6773 * ctx - the redis module context provided to for the scan.
6774 * keyname - owned by the caller and need to be retained if used after this
6775 * function.
6776 *
6777 * key - holds info on the key and value, it is provided as best effort, in
6778 * some cases it might be NULL, in which case the user should (can) use
6779 * RedisModule_OpenKey (and CloseKey too).
6780 * when it is provided, it is owned by the caller and will be free when the
6781 * callback returns.
6782 *
6783 * privdata - the user data provided to RedisModule_Scan.
6784 *
6785 * The way it should be used:
6786 * RedisModuleCursor *c = RedisModule_ScanCursorCreate();
6787 * while(RedisModule_Scan(ctx, c, callback, privateData));
6788 * RedisModule_ScanCursorDestroy(c);
6789 *
6790 * It is also possible to use this API from another thread while the lock
6791 * is acquired during the actuall call to RM_Scan:
6792 *
6793 * RedisModuleCursor *c = RedisModule_ScanCursorCreate();
6794 * RedisModule_ThreadSafeContextLock(ctx);
6795 * while(RedisModule_Scan(ctx, c, callback, privateData)){
6796 * RedisModule_ThreadSafeContextUnlock(ctx);
6797 * // do some background job
6798 * RedisModule_ThreadSafeContextLock(ctx);
6799 * }
6800 * RedisModule_ScanCursorDestroy(c);
6801 *
6802 * The function will return 1 if there are more elements to scan and
6803 * 0 otherwise, possibly setting errno if the call failed.
6804 *
6805 * It is also possible to restart an existing cursor using RM_ScanCursorRestart.
6806 *
6807 * IMPORTANT: This API is very similar to the Redis SCAN command from the
6808 * point of view of the guarantees it provides. This means that the API
6809 * may report duplicated keys, but guarantees to report at least one time
6810 * every key that was there from the start to the end of the scanning process.
6811 *
6812 * NOTE: If you do database changes within the callback, you should be aware
6813 * that the internal state of the database may change. For instance it is safe
6814 * to delete or modify the current key, but may not be safe to delete any
6815 * other key.
6816 * Moreover playing with the Redis keyspace while iterating may have the
6817 * effect of returning more duplicates. A safe pattern is to store the keys
6818 * names you want to modify elsewhere, and perform the actions on the keys
6819 * later when the iteration is complete. However this can cost a lot of
6820 * memory, so it may make sense to just operate on the current key when
6821 * possible during the iteration, given that this is safe. */
RM_Scan(RedisModuleCtx * ctx,RedisModuleScanCursor * cursor,RedisModuleScanCB fn,void * privdata)6822 int RM_Scan(RedisModuleCtx *ctx, RedisModuleScanCursor *cursor, RedisModuleScanCB fn, void *privdata) {
6823 if (cursor->done) {
6824 errno = ENOENT;
6825 return 0;
6826 }
6827 int ret = 1;
6828 ScanCBData data = { ctx, privdata, fn };
6829 cursor->cursor = dictScan(ctx->client->db->dict, cursor->cursor, moduleScanCallback, NULL, &data);
6830 if (cursor->cursor == 0) {
6831 cursor->done = 1;
6832 ret = 0;
6833 }
6834 errno = 0;
6835 return ret;
6836 }
6837
6838 typedef void (*RedisModuleScanKeyCB)(RedisModuleKey *key, RedisModuleString *field, RedisModuleString *value, void *privdata);
6839 typedef struct {
6840 RedisModuleKey *key;
6841 void* user_data;
6842 RedisModuleScanKeyCB fn;
6843 } ScanKeyCBData;
6844
moduleScanKeyCallback(void * privdata,const dictEntry * de)6845 static void moduleScanKeyCallback(void *privdata, const dictEntry *de) {
6846 ScanKeyCBData *data = privdata;
6847 sds key = dictGetKey(de);
6848 robj *o = data->key->value;
6849 robj *field = createStringObject(key, sdslen(key));
6850 robj *value = NULL;
6851 if (o->type == OBJ_SET) {
6852 value = NULL;
6853 } else if (o->type == OBJ_HASH) {
6854 sds val = dictGetVal(de);
6855 value = createStringObject(val, sdslen(val));
6856 } else if (o->type == OBJ_ZSET) {
6857 double *val = (double*)dictGetVal(de);
6858 value = createStringObjectFromLongDouble(*val, 0);
6859 }
6860
6861 data->fn(data->key, field, value, data->user_data);
6862 decrRefCount(field);
6863 if (value) decrRefCount(value);
6864 }
6865
6866 /* Scan api that allows a module to scan the elements in a hash, set or sorted set key
6867 *
6868 * Callback for scan implementation.
6869 * void scan_callback(RedisModuleKey *key, RedisModuleString* field, RedisModuleString* value, void *privdata);
6870 * - key - the redis key context provided to for the scan.
6871 * - field - field name, owned by the caller and need to be retained if used
6872 * after this function.
6873 * - value - value string or NULL for set type, owned by the caller and need to
6874 * be retained if used after this function.
6875 * - privdata - the user data provided to RedisModule_ScanKey.
6876 *
6877 * The way it should be used:
6878 * RedisModuleCursor *c = RedisModule_ScanCursorCreate();
6879 * RedisModuleKey *key = RedisModule_OpenKey(...)
6880 * while(RedisModule_ScanKey(key, c, callback, privateData));
6881 * RedisModule_CloseKey(key);
6882 * RedisModule_ScanCursorDestroy(c);
6883 *
6884 * It is also possible to use this API from another thread while the lock is acquired during
6885 * the actuall call to RM_ScanKey, and re-opening the key each time:
6886 * RedisModuleCursor *c = RedisModule_ScanCursorCreate();
6887 * RedisModule_ThreadSafeContextLock(ctx);
6888 * RedisModuleKey *key = RedisModule_OpenKey(...)
6889 * while(RedisModule_ScanKey(ctx, c, callback, privateData)){
6890 * RedisModule_CloseKey(key);
6891 * RedisModule_ThreadSafeContextUnlock(ctx);
6892 * // do some background job
6893 * RedisModule_ThreadSafeContextLock(ctx);
6894 * RedisModuleKey *key = RedisModule_OpenKey(...)
6895 * }
6896 * RedisModule_CloseKey(key);
6897 * RedisModule_ScanCursorDestroy(c);
6898 *
6899 * The function will return 1 if there are more elements to scan and 0 otherwise,
6900 * possibly setting errno if the call failed.
6901 * It is also possible to restart an existing cursor using RM_ScanCursorRestart.
6902 *
6903 * NOTE: Certain operations are unsafe while iterating the object. For instance
6904 * while the API guarantees to return at least one time all the elements that
6905 * are present in the data structure consistently from the start to the end
6906 * of the iteration (see HSCAN and similar commands documentation), the more
6907 * you play with the elements, the more duplicates you may get. In general
6908 * deleting the current element of the data structure is safe, while removing
6909 * the key you are iterating is not safe. */
RM_ScanKey(RedisModuleKey * key,RedisModuleScanCursor * cursor,RedisModuleScanKeyCB fn,void * privdata)6910 int RM_ScanKey(RedisModuleKey *key, RedisModuleScanCursor *cursor, RedisModuleScanKeyCB fn, void *privdata) {
6911 if (key == NULL || key->value == NULL) {
6912 errno = EINVAL;
6913 return 0;
6914 }
6915 dict *ht = NULL;
6916 robj *o = key->value;
6917 if (o->type == OBJ_SET) {
6918 if (o->encoding == OBJ_ENCODING_HT)
6919 ht = o->ptr;
6920 } else if (o->type == OBJ_HASH) {
6921 if (o->encoding == OBJ_ENCODING_HT)
6922 ht = o->ptr;
6923 } else if (o->type == OBJ_ZSET) {
6924 if (o->encoding == OBJ_ENCODING_SKIPLIST)
6925 ht = ((zset *)o->ptr)->dict;
6926 } else {
6927 errno = EINVAL;
6928 return 0;
6929 }
6930 if (cursor->done) {
6931 errno = ENOENT;
6932 return 0;
6933 }
6934 int ret = 1;
6935 if (ht) {
6936 ScanKeyCBData data = { key, privdata, fn };
6937 cursor->cursor = dictScan(ht, cursor->cursor, moduleScanKeyCallback, NULL, &data);
6938 if (cursor->cursor == 0) {
6939 cursor->done = 1;
6940 ret = 0;
6941 }
6942 } else if (o->type == OBJ_SET && o->encoding == OBJ_ENCODING_INTSET) {
6943 int pos = 0;
6944 int64_t ll;
6945 while(intsetGet(o->ptr,pos++,&ll)) {
6946 robj *field = createObject(OBJ_STRING,sdsfromlonglong(ll));
6947 fn(key, field, NULL, privdata);
6948 decrRefCount(field);
6949 }
6950 cursor->cursor = 1;
6951 cursor->done = 1;
6952 ret = 0;
6953 } else if (o->type == OBJ_HASH || o->type == OBJ_ZSET) {
6954 unsigned char *p = ziplistIndex(o->ptr,0);
6955 unsigned char *vstr;
6956 unsigned int vlen;
6957 long long vll;
6958 while(p) {
6959 ziplistGet(p,&vstr,&vlen,&vll);
6960 robj *field = (vstr != NULL) ?
6961 createStringObject((char*)vstr,vlen) :
6962 createObject(OBJ_STRING,sdsfromlonglong(vll));
6963 p = ziplistNext(o->ptr,p);
6964 ziplistGet(p,&vstr,&vlen,&vll);
6965 robj *value = (vstr != NULL) ?
6966 createStringObject((char*)vstr,vlen) :
6967 createObject(OBJ_STRING,sdsfromlonglong(vll));
6968 fn(key, field, value, privdata);
6969 p = ziplistNext(o->ptr,p);
6970 decrRefCount(field);
6971 decrRefCount(value);
6972 }
6973 cursor->cursor = 1;
6974 cursor->done = 1;
6975 ret = 0;
6976 }
6977 errno = 0;
6978 return ret;
6979 }
6980
6981
6982 /* --------------------------------------------------------------------------
6983 * Module fork API
6984 * -------------------------------------------------------------------------- */
6985
6986 /* Create a background child process with the current frozen snaphost of the
6987 * main process where you can do some processing in the background without
6988 * affecting / freezing the traffic and no need for threads and GIL locking.
6989 * Note that Redis allows for only one concurrent fork.
6990 * When the child wants to exit, it should call RedisModule_ExitFromChild.
6991 * If the parent wants to kill the child it should call RedisModule_KillForkChild
6992 * The done handler callback will be executed on the parent process when the
6993 * child existed (but not when killed)
6994 * Return: -1 on failure, on success the parent process will get a positive PID
6995 * of the child, and the child process will get 0.
6996 */
RM_Fork(RedisModuleForkDoneHandler cb,void * user_data)6997 int RM_Fork(RedisModuleForkDoneHandler cb, void *user_data) {
6998 pid_t childpid;
6999 if (hasActiveChildProcess()) {
7000 return -1;
7001 }
7002
7003 openChildInfoPipe();
7004 if ((childpid = redisFork(CHILD_TYPE_MODULE)) == 0) {
7005 /* Child */
7006 redisSetProcTitle("redis-module-fork");
7007 } else if (childpid == -1) {
7008 closeChildInfoPipe();
7009 serverLog(LL_WARNING,"Can't fork for module: %s", strerror(errno));
7010 } else {
7011 /* Parent */
7012 server.module_child_pid = childpid;
7013 moduleForkInfo.done_handler = cb;
7014 moduleForkInfo.done_handler_user_data = user_data;
7015 updateDictResizePolicy();
7016 serverLog(LL_VERBOSE, "Module fork started pid: %d ", childpid);
7017 }
7018 return childpid;
7019 }
7020
7021 /* Call from the child process when you want to terminate it.
7022 * retcode will be provided to the done handler executed on the parent process.
7023 */
RM_ExitFromChild(int retcode)7024 int RM_ExitFromChild(int retcode) {
7025 sendChildCOWInfo(CHILD_TYPE_MODULE, "Module fork");
7026 exitFromChild(retcode);
7027 return REDISMODULE_OK;
7028 }
7029
7030 /* Kill the active module forked child, if there is one active and the
7031 * pid matches, and returns C_OK. Otherwise if there is no active module
7032 * child or the pid does not match, return C_ERR without doing anything. */
TerminateModuleForkChild(int child_pid,int wait)7033 int TerminateModuleForkChild(int child_pid, int wait) {
7034 /* Module child should be active and pid should match. */
7035 if (server.module_child_pid == -1 ||
7036 server.module_child_pid != child_pid) return C_ERR;
7037
7038 int statloc;
7039 serverLog(LL_VERBOSE,"Killing running module fork child: %ld",
7040 (long) server.module_child_pid);
7041 if (kill(server.module_child_pid,SIGUSR1) != -1 && wait) {
7042 while(wait4(server.module_child_pid,&statloc,0,NULL) !=
7043 server.module_child_pid);
7044 }
7045 /* Reset the buffer accumulating changes while the child saves. */
7046 server.module_child_pid = -1;
7047 moduleForkInfo.done_handler = NULL;
7048 moduleForkInfo.done_handler_user_data = NULL;
7049 closeChildInfoPipe();
7050 updateDictResizePolicy();
7051 return C_OK;
7052 }
7053
7054 /* Can be used to kill the forked child process from the parent process.
7055 * child_pid would be the return value of RedisModule_Fork. */
RM_KillForkChild(int child_pid)7056 int RM_KillForkChild(int child_pid) {
7057 /* Kill module child, wait for child exit. */
7058 if (TerminateModuleForkChild(child_pid,1) == C_OK)
7059 return REDISMODULE_OK;
7060 else
7061 return REDISMODULE_ERR;
7062 }
7063
ModuleForkDoneHandler(int exitcode,int bysignal)7064 void ModuleForkDoneHandler(int exitcode, int bysignal) {
7065 serverLog(LL_NOTICE,
7066 "Module fork exited pid: %d, retcode: %d, bysignal: %d",
7067 server.module_child_pid, exitcode, bysignal);
7068 if (moduleForkInfo.done_handler) {
7069 moduleForkInfo.done_handler(exitcode, bysignal,
7070 moduleForkInfo.done_handler_user_data);
7071 }
7072 server.module_child_pid = -1;
7073 moduleForkInfo.done_handler = NULL;
7074 moduleForkInfo.done_handler_user_data = NULL;
7075 }
7076
7077 /* --------------------------------------------------------------------------
7078 * Server hooks implementation
7079 * -------------------------------------------------------------------------- */
7080
7081 /* Register to be notified, via a callback, when the specified server event
7082 * happens. The callback is called with the event as argument, and an additional
7083 * argument which is a void pointer and should be cased to a specific type
7084 * that is event-specific (but many events will just use NULL since they do not
7085 * have additional information to pass to the callback).
7086 *
7087 * If the callback is NULL and there was a previous subscription, the module
7088 * will be unsubscribed. If there was a previous subscription and the callback
7089 * is not null, the old callback will be replaced with the new one.
7090 *
7091 * The callback must be of this type:
7092 *
7093 * int (*RedisModuleEventCallback)(RedisModuleCtx *ctx,
7094 * RedisModuleEvent eid,
7095 * uint64_t subevent,
7096 * void *data);
7097 *
7098 * The 'ctx' is a normal Redis module context that the callback can use in
7099 * order to call other modules APIs. The 'eid' is the event itself, this
7100 * is only useful in the case the module subscribed to multiple events: using
7101 * the 'id' field of this structure it is possible to check if the event
7102 * is one of the events we registered with this callback. The 'subevent' field
7103 * depends on the event that fired.
7104 *
7105 * Finally the 'data' pointer may be populated, only for certain events, with
7106 * more relevant data.
7107 *
7108 * Here is a list of events you can use as 'eid' and related sub events:
7109 *
7110 * RedisModuleEvent_ReplicationRoleChanged
7111 *
7112 * This event is called when the instance switches from master
7113 * to replica or the other way around, however the event is
7114 * also called when the replica remains a replica but starts to
7115 * replicate with a different master.
7116 *
7117 * The following sub events are available:
7118 *
7119 * REDISMODULE_SUBEVENT_REPLROLECHANGED_NOW_MASTER
7120 * REDISMODULE_SUBEVENT_REPLROLECHANGED_NOW_REPLICA
7121 *
7122 * The 'data' field can be casted by the callback to a
7123 * RedisModuleReplicationInfo structure with the following fields:
7124 *
7125 * int master; // true if master, false if replica
7126 * char *masterhost; // master instance hostname for NOW_REPLICA
7127 * int masterport; // master instance port for NOW_REPLICA
7128 * char *replid1; // Main replication ID
7129 * char *replid2; // Secondary replication ID
7130 * uint64_t repl1_offset; // Main replication offset
7131 * uint64_t repl2_offset; // Offset of replid2 validity
7132 *
7133 * RedisModuleEvent_Persistence
7134 *
7135 * This event is called when RDB saving or AOF rewriting starts
7136 * and ends. The following sub events are available:
7137 *
7138 * REDISMODULE_SUBEVENT_PERSISTENCE_RDB_START
7139 * REDISMODULE_SUBEVENT_PERSISTENCE_AOF_START
7140 * REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_RDB_START
7141 * REDISMODULE_SUBEVENT_PERSISTENCE_ENDED
7142 * REDISMODULE_SUBEVENT_PERSISTENCE_FAILED
7143 *
7144 * The above events are triggered not just when the user calls the
7145 * relevant commands like BGSAVE, but also when a saving operation
7146 * or AOF rewriting occurs because of internal server triggers.
7147 * The SYNC_RDB_START sub events are happening in the forground due to
7148 * SAVE command, FLUSHALL, or server shutdown, and the other RDB and
7149 * AOF sub events are executed in a background fork child, so any
7150 * action the module takes can only affect the generated AOF or RDB,
7151 * but will not be reflected in the parent process and affect connected
7152 * clients and commands. Also note that the AOF_START sub event may end
7153 * up saving RDB content in case of an AOF with rdb-preamble.
7154 *
7155 * RedisModuleEvent_FlushDB
7156 *
7157 * The FLUSHALL, FLUSHDB or an internal flush (for instance
7158 * because of replication, after the replica synchronization)
7159 * happened. The following sub events are available:
7160 *
7161 * REDISMODULE_SUBEVENT_FLUSHDB_START
7162 * REDISMODULE_SUBEVENT_FLUSHDB_END
7163 *
7164 * The data pointer can be casted to a RedisModuleFlushInfo
7165 * structure with the following fields:
7166 *
7167 * int32_t async; // True if the flush is done in a thread.
7168 * See for instance FLUSHALL ASYNC.
7169 * In this case the END callback is invoked
7170 * immediately after the database is put
7171 * in the free list of the thread.
7172 * int32_t dbnum; // Flushed database number, -1 for all the DBs
7173 * in the case of the FLUSHALL operation.
7174 *
7175 * The start event is called *before* the operation is initated, thus
7176 * allowing the callback to call DBSIZE or other operation on the
7177 * yet-to-free keyspace.
7178 *
7179 * RedisModuleEvent_Loading
7180 *
7181 * Called on loading operations: at startup when the server is
7182 * started, but also after a first synchronization when the
7183 * replica is loading the RDB file from the master.
7184 * The following sub events are available:
7185 *
7186 * REDISMODULE_SUBEVENT_LOADING_RDB_START
7187 * REDISMODULE_SUBEVENT_LOADING_AOF_START
7188 * REDISMODULE_SUBEVENT_LOADING_REPL_START
7189 * REDISMODULE_SUBEVENT_LOADING_ENDED
7190 * REDISMODULE_SUBEVENT_LOADING_FAILED
7191 *
7192 * Note that AOF loading may start with an RDB data in case of
7193 * rdb-preamble, in which case you'll only receive an AOF_START event.
7194 *
7195 *
7196 * RedisModuleEvent_ClientChange
7197 *
7198 * Called when a client connects or disconnects.
7199 * The data pointer can be casted to a RedisModuleClientInfo
7200 * structure, documented in RedisModule_GetClientInfoById().
7201 * The following sub events are available:
7202 *
7203 * REDISMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED
7204 * REDISMODULE_SUBEVENT_CLIENT_CHANGE_DISCONNECTED
7205 *
7206 * RedisModuleEvent_Shutdown
7207 *
7208 * The server is shutting down. No subevents are available.
7209 *
7210 * RedisModuleEvent_ReplicaChange
7211 *
7212 * This event is called when the instance (that can be both a
7213 * master or a replica) get a new online replica, or lose a
7214 * replica since it gets disconnected.
7215 * The following sub events are available:
7216 *
7217 * REDISMODULE_SUBEVENT_REPLICA_CHANGE_ONLINE
7218 * REDISMODULE_SUBEVENT_REPLICA_CHANGE_OFFLINE
7219 *
7220 * No additional information is available so far: future versions
7221 * of Redis will have an API in order to enumerate the replicas
7222 * connected and their state.
7223 *
7224 * RedisModuleEvent_CronLoop
7225 *
7226 * This event is called every time Redis calls the serverCron()
7227 * function in order to do certain bookkeeping. Modules that are
7228 * required to do operations from time to time may use this callback.
7229 * Normally Redis calls this function 10 times per second, but
7230 * this changes depending on the "hz" configuration.
7231 * No sub events are available.
7232 *
7233 * The data pointer can be casted to a RedisModuleCronLoop
7234 * structure with the following fields:
7235 *
7236 * int32_t hz; // Approximate number of events per second.
7237 *
7238 * RedisModuleEvent_MasterLinkChange
7239 *
7240 * This is called for replicas in order to notify when the
7241 * replication link becomes functional (up) with our master,
7242 * or when it goes down. Note that the link is not considered
7243 * up when we just connected to the master, but only if the
7244 * replication is happening correctly.
7245 * The following sub events are available:
7246 *
7247 * REDISMODULE_SUBEVENT_MASTER_LINK_UP
7248 * REDISMODULE_SUBEVENT_MASTER_LINK_DOWN
7249 *
7250 * RedisModuleEvent_ModuleChange
7251 *
7252 * This event is called when a new module is loaded or one is unloaded.
7253 * The following sub events are available:
7254 *
7255 * REDISMODULE_SUBEVENT_MODULE_LOADED
7256 * REDISMODULE_SUBEVENT_MODULE_UNLOADED
7257 *
7258 * The data pointer can be casted to a RedisModuleModuleChange
7259 * structure with the following fields:
7260 *
7261 * const char* module_name; // Name of module loaded or unloaded.
7262 * int32_t module_version; // Module version.
7263 *
7264 * RedisModuleEvent_LoadingProgress
7265 *
7266 * This event is called repeatedly called while an RDB or AOF file
7267 * is being loaded.
7268 * The following sub events are availble:
7269 *
7270 * REDISMODULE_SUBEVENT_LOADING_PROGRESS_RDB
7271 * REDISMODULE_SUBEVENT_LOADING_PROGRESS_AOF
7272 *
7273 * The data pointer can be casted to a RedisModuleLoadingProgress
7274 * structure with the following fields:
7275 *
7276 * int32_t hz; // Approximate number of events per second.
7277 * int32_t progress; // Approximate progress between 0 and 1024,
7278 * or -1 if unknown.
7279 *
7280 * RedisModuleEvent_SwapDB
7281 *
7282 * This event is called when a swap db command has been successfully
7283 * Executed.
7284 * For this event call currently there is no subevents available.
7285 *
7286 * The data pointer can be casted to a RedisModuleSwapDbInfo
7287 * structure with the following fields:
7288 *
7289 * int32_t dbnum_first; // Swap Db first dbnum
7290 * int32_t dbnum_second; // Swap Db second dbnum
7291 *
7292 *
7293 *
7294 * The function returns REDISMODULE_OK if the module was successfully subscribed
7295 * for the specified event. If the API is called from a wrong context or unsupported event
7296 * is given then REDISMODULE_ERR is returned. */
RM_SubscribeToServerEvent(RedisModuleCtx * ctx,RedisModuleEvent event,RedisModuleEventCallback callback)7297 int RM_SubscribeToServerEvent(RedisModuleCtx *ctx, RedisModuleEvent event, RedisModuleEventCallback callback) {
7298 RedisModuleEventListener *el;
7299
7300 /* Protect in case of calls from contexts without a module reference. */
7301 if (ctx->module == NULL) return REDISMODULE_ERR;
7302 if (event.id >= _REDISMODULE_EVENT_NEXT) return REDISMODULE_ERR;
7303
7304 /* Search an event matching this module and event ID. */
7305 listIter li;
7306 listNode *ln;
7307 listRewind(RedisModule_EventListeners,&li);
7308 while((ln = listNext(&li))) {
7309 el = ln->value;
7310 if (el->module == ctx->module && el->event.id == event.id)
7311 break; /* Matching event found. */
7312 }
7313
7314 /* Modify or remove the event listener if we already had one. */
7315 if (ln) {
7316 if (callback == NULL) {
7317 listDelNode(RedisModule_EventListeners,ln);
7318 zfree(el);
7319 } else {
7320 el->callback = callback; /* Update the callback with the new one. */
7321 }
7322 return REDISMODULE_OK;
7323 }
7324
7325 /* No event found, we need to add a new one. */
7326 el = zmalloc(sizeof(*el));
7327 el->module = ctx->module;
7328 el->event = event;
7329 el->callback = callback;
7330 listAddNodeTail(RedisModule_EventListeners,el);
7331 return REDISMODULE_OK;
7332 }
7333
7334 /**
7335 * For a given server event and subevent, return zero if the
7336 * subevent is not supported and non-zero otherwise.
7337 */
RM_IsSubEventSupported(RedisModuleEvent event,int64_t subevent)7338 int RM_IsSubEventSupported(RedisModuleEvent event, int64_t subevent) {
7339 switch (event.id) {
7340 case REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED:
7341 return subevent < _REDISMODULE_EVENT_REPLROLECHANGED_NEXT;
7342 case REDISMODULE_EVENT_PERSISTENCE:
7343 return subevent < _REDISMODULE_SUBEVENT_PERSISTENCE_NEXT;
7344 case REDISMODULE_EVENT_FLUSHDB:
7345 return subevent < _REDISMODULE_SUBEVENT_FLUSHDB_NEXT;
7346 case REDISMODULE_EVENT_LOADING:
7347 return subevent < _REDISMODULE_SUBEVENT_LOADING_NEXT;
7348 case REDISMODULE_EVENT_CLIENT_CHANGE:
7349 return subevent < _REDISMODULE_SUBEVENT_CLIENT_CHANGE_NEXT;
7350 case REDISMODULE_EVENT_SHUTDOWN:
7351 return subevent < _REDISMODULE_SUBEVENT_SHUTDOWN_NEXT;
7352 case REDISMODULE_EVENT_REPLICA_CHANGE:
7353 return subevent < _REDISMODULE_EVENT_REPLROLECHANGED_NEXT;
7354 case REDISMODULE_EVENT_MASTER_LINK_CHANGE:
7355 return subevent < _REDISMODULE_SUBEVENT_MASTER_NEXT;
7356 case REDISMODULE_EVENT_CRON_LOOP:
7357 return subevent < _REDISMODULE_SUBEVENT_CRON_LOOP_NEXT;
7358 case REDISMODULE_EVENT_MODULE_CHANGE:
7359 return subevent < _REDISMODULE_SUBEVENT_MODULE_NEXT;
7360 case REDISMODULE_EVENT_LOADING_PROGRESS:
7361 return subevent < _REDISMODULE_SUBEVENT_LOADING_PROGRESS_NEXT;
7362 case REDISMODULE_EVENT_SWAPDB:
7363 return subevent < _REDISMODULE_SUBEVENT_SWAPDB_NEXT;
7364 default:
7365 break;
7366 }
7367 return 0;
7368 }
7369
7370 /* This is called by the Redis internals every time we want to fire an
7371 * event that can be interceppted by some module. The pointer 'data' is useful
7372 * in order to populate the event-specific structure when needed, in order
7373 * to return the structure with more information to the callback.
7374 *
7375 * 'eid' and 'subid' are just the main event ID and the sub event associated
7376 * with the event, depending on what exactly happened. */
moduleFireServerEvent(uint64_t eid,int subid,void * data)7377 void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
7378 /* Fast path to return ASAP if there is nothing to do, avoiding to
7379 * setup the iterator and so forth: we want this call to be extremely
7380 * cheap if there are no registered modules. */
7381 if (listLength(RedisModule_EventListeners) == 0) return;
7382
7383 int real_client_used = 0;
7384 listIter li;
7385 listNode *ln;
7386 listRewind(RedisModule_EventListeners,&li);
7387 while((ln = listNext(&li))) {
7388 RedisModuleEventListener *el = ln->value;
7389 if (el->event.id == eid) {
7390 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
7391 ctx.module = el->module;
7392
7393 if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) {
7394 /* In the case of client changes, we're pushing the real client
7395 * so the event handler can mutate it if needed. For example,
7396 * to change its authentication state in a way that does not
7397 * depend on specific commands executed later.
7398 */
7399 ctx.client = (client *) data;
7400 real_client_used = 1;
7401 } else if (ModulesInHooks == 0) {
7402 ctx.client = moduleFreeContextReusedClient;
7403 } else {
7404 ctx.client = createClient(NULL);
7405 ctx.client->flags |= CLIENT_MODULE;
7406 ctx.client->user = NULL; /* Root user. */
7407 }
7408
7409 void *moduledata = NULL;
7410 RedisModuleClientInfoV1 civ1;
7411 RedisModuleReplicationInfoV1 riv1;
7412 RedisModuleModuleChangeV1 mcv1;
7413 /* Start at DB zero by default when calling the handler. It's
7414 * up to the specific event setup to change it when it makes
7415 * sense. For instance for FLUSHDB events we select the correct
7416 * DB automatically. */
7417 selectDb(ctx.client, 0);
7418
7419 /* Event specific context and data pointer setup. */
7420 if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) {
7421 modulePopulateClientInfoStructure(&civ1,data,
7422 el->event.dataver);
7423 moduledata = &civ1;
7424 } else if (eid == REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED) {
7425 modulePopulateReplicationInfoStructure(&riv1,el->event.dataver);
7426 moduledata = &riv1;
7427 } else if (eid == REDISMODULE_EVENT_FLUSHDB) {
7428 moduledata = data;
7429 RedisModuleFlushInfoV1 *fi = data;
7430 if (fi->dbnum != -1)
7431 selectDb(ctx.client, fi->dbnum);
7432 } else if (eid == REDISMODULE_EVENT_MODULE_CHANGE) {
7433 RedisModule *m = data;
7434 if (m == el->module)
7435 continue;
7436 mcv1.version = REDISMODULE_MODULE_CHANGE_VERSION;
7437 mcv1.module_name = m->name;
7438 mcv1.module_version = m->ver;
7439 moduledata = &mcv1;
7440 } else if (eid == REDISMODULE_EVENT_LOADING_PROGRESS) {
7441 moduledata = data;
7442 } else if (eid == REDISMODULE_EVENT_CRON_LOOP) {
7443 moduledata = data;
7444 } else if (eid == REDISMODULE_EVENT_SWAPDB) {
7445 moduledata = data;
7446 }
7447
7448 ModulesInHooks++;
7449 el->module->in_hook++;
7450 el->callback(&ctx,el->event,subid,moduledata);
7451 el->module->in_hook--;
7452 ModulesInHooks--;
7453
7454 if (ModulesInHooks != 0 && !real_client_used) freeClient(ctx.client);
7455 moduleFreeContext(&ctx);
7456 }
7457 }
7458 }
7459
7460 /* Remove all the listeners for this module: this is used before unloading
7461 * a module. */
moduleUnsubscribeAllServerEvents(RedisModule * module)7462 void moduleUnsubscribeAllServerEvents(RedisModule *module) {
7463 RedisModuleEventListener *el;
7464 listIter li;
7465 listNode *ln;
7466 listRewind(RedisModule_EventListeners,&li);
7467
7468 while((ln = listNext(&li))) {
7469 el = ln->value;
7470 if (el->module == module) {
7471 listDelNode(RedisModule_EventListeners,ln);
7472 zfree(el);
7473 }
7474 }
7475 }
7476
processModuleLoadingProgressEvent(int is_aof)7477 void processModuleLoadingProgressEvent(int is_aof) {
7478 long long now = ustime();
7479 static long long next_event = 0;
7480 if (now >= next_event) {
7481 /* Fire the loading progress modules end event. */
7482 int progress = -1;
7483 if (server.loading_total_bytes)
7484 progress = (server.loading_loaded_bytes<<10) / server.loading_total_bytes;
7485 RedisModuleLoadingProgressV1 fi = {REDISMODULE_LOADING_PROGRESS_VERSION,
7486 server.hz,
7487 progress};
7488 moduleFireServerEvent(REDISMODULE_EVENT_LOADING_PROGRESS,
7489 is_aof?
7490 REDISMODULE_SUBEVENT_LOADING_PROGRESS_AOF:
7491 REDISMODULE_SUBEVENT_LOADING_PROGRESS_RDB,
7492 &fi);
7493 /* decide when the next event should fire. */
7494 next_event = now + 1000000 / server.hz;
7495 }
7496 }
7497
7498 /* --------------------------------------------------------------------------
7499 * Modules API internals
7500 * -------------------------------------------------------------------------- */
7501
7502 /* server.moduleapi dictionary type. Only uses plain C strings since
7503 * this gets queries from modules. */
7504
dictCStringKeyHash(const void * key)7505 uint64_t dictCStringKeyHash(const void *key) {
7506 return dictGenHashFunction((unsigned char*)key, strlen((char*)key));
7507 }
7508
dictCStringKeyCompare(void * privdata,const void * key1,const void * key2)7509 int dictCStringKeyCompare(void *privdata, const void *key1, const void *key2) {
7510 UNUSED(privdata);
7511 return strcmp(key1,key2) == 0;
7512 }
7513
7514 dictType moduleAPIDictType = {
7515 dictCStringKeyHash, /* hash function */
7516 NULL, /* key dup */
7517 NULL, /* val dup */
7518 dictCStringKeyCompare, /* key compare */
7519 NULL, /* key destructor */
7520 NULL /* val destructor */
7521 };
7522
moduleRegisterApi(const char * funcname,void * funcptr)7523 int moduleRegisterApi(const char *funcname, void *funcptr) {
7524 return dictAdd(server.moduleapi, (char*)funcname, funcptr);
7525 }
7526
7527 #define REGISTER_API(name) \
7528 moduleRegisterApi("RedisModule_" #name, (void *)(unsigned long)RM_ ## name)
7529
7530 /* Global initialization at Redis startup. */
7531 void moduleRegisterCoreAPI(void);
7532
moduleInitModulesSystem(void)7533 void moduleInitModulesSystem(void) {
7534 moduleUnblockedClients = listCreate();
7535 server.loadmodule_queue = listCreate();
7536 modules = dictCreate(&modulesDictType,NULL);
7537
7538 /* Set up the keyspace notification subscriber list and static client */
7539 moduleKeyspaceSubscribers = listCreate();
7540 moduleFreeContextReusedClient = createClient(NULL);
7541 moduleFreeContextReusedClient->flags |= CLIENT_MODULE;
7542 moduleFreeContextReusedClient->user = NULL; /* root user. */
7543
7544 /* Set up filter list */
7545 moduleCommandFilters = listCreate();
7546
7547 moduleRegisterCoreAPI();
7548 if (pipe(server.module_blocked_pipe) == -1) {
7549 serverLog(LL_WARNING,
7550 "Can't create the pipe for module blocking commands: %s",
7551 strerror(errno));
7552 exit(1);
7553 }
7554 /* Make the pipe non blocking. This is just a best effort aware mechanism
7555 * and we do not want to block not in the read nor in the write half. */
7556 anetNonBlock(NULL,server.module_blocked_pipe[0]);
7557 anetNonBlock(NULL,server.module_blocked_pipe[1]);
7558
7559 /* Create the timers radix tree. */
7560 Timers = raxNew();
7561
7562 /* Setup the event listeners data structures. */
7563 RedisModule_EventListeners = listCreate();
7564
7565 /* Our thread-safe contexts GIL must start with already locked:
7566 * it is just unlocked when it's safe. */
7567 pthread_mutex_lock(&moduleGIL);
7568 }
7569
7570 /* Load all the modules in the server.loadmodule_queue list, which is
7571 * populated by `loadmodule` directives in the configuration file.
7572 * We can't load modules directly when processing the configuration file
7573 * because the server must be fully initialized before loading modules.
7574 *
7575 * The function aborts the server on errors, since to start with missing
7576 * modules is not considered sane: clients may rely on the existence of
7577 * given commands, loading AOF also may need some modules to exist, and
7578 * if this instance is a slave, it must understand commands from master. */
moduleLoadFromQueue(void)7579 void moduleLoadFromQueue(void) {
7580 listIter li;
7581 listNode *ln;
7582
7583 listRewind(server.loadmodule_queue,&li);
7584 while((ln = listNext(&li))) {
7585 struct moduleLoadQueueEntry *loadmod = ln->value;
7586 if (moduleLoad(loadmod->path,(void **)loadmod->argv,loadmod->argc)
7587 == C_ERR)
7588 {
7589 serverLog(LL_WARNING,
7590 "Can't load module from %s: server aborting",
7591 loadmod->path);
7592 exit(1);
7593 }
7594 }
7595 }
7596
moduleFreeModuleStructure(struct RedisModule * module)7597 void moduleFreeModuleStructure(struct RedisModule *module) {
7598 listRelease(module->types);
7599 listRelease(module->filters);
7600 listRelease(module->usedby);
7601 listRelease(module->using);
7602 sdsfree(module->name);
7603 zfree(module);
7604 }
7605
moduleUnregisterCommands(struct RedisModule * module)7606 void moduleUnregisterCommands(struct RedisModule *module) {
7607 /* Unregister all the commands registered by this module. */
7608 dictIterator *di = dictGetSafeIterator(server.commands);
7609 dictEntry *de;
7610 while ((de = dictNext(di)) != NULL) {
7611 struct redisCommand *cmd = dictGetVal(de);
7612 if (cmd->proc == RedisModuleCommandDispatcher) {
7613 RedisModuleCommandProxy *cp =
7614 (void*)(unsigned long)cmd->getkeys_proc;
7615 sds cmdname = cp->rediscmd->name;
7616 if (cp->module == module) {
7617 dictDelete(server.commands,cmdname);
7618 dictDelete(server.orig_commands,cmdname);
7619 sdsfree(cmdname);
7620 zfree(cp->rediscmd);
7621 zfree(cp);
7622 }
7623 }
7624 }
7625 dictReleaseIterator(di);
7626 }
7627
7628 /* Load a module and initialize it. On success C_OK is returned, otherwise
7629 * C_ERR is returned. */
moduleLoad(const char * path,void ** module_argv,int module_argc)7630 int moduleLoad(const char *path, void **module_argv, int module_argc) {
7631 int (*onload)(void *, void **, int);
7632 void *handle;
7633 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
7634 ctx.client = moduleFreeContextReusedClient;
7635 selectDb(ctx.client, 0);
7636
7637 struct stat st;
7638 if (stat(path, &st) == 0)
7639 { // this check is best effort
7640 if (!(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
7641 serverLog(LL_WARNING, "Module %s failed to load: It does not have execute permissions.", path);
7642 return C_ERR;
7643 }
7644 }
7645
7646 handle = dlopen(path,RTLD_NOW|RTLD_LOCAL);
7647 if (handle == NULL) {
7648 serverLog(LL_WARNING, "Module %s failed to load: %s", path, dlerror());
7649 return C_ERR;
7650 }
7651 onload = (int (*)(void *, void **, int))(unsigned long) dlsym(handle,"RedisModule_OnLoad");
7652 if (onload == NULL) {
7653 dlclose(handle);
7654 serverLog(LL_WARNING,
7655 "Module %s does not export RedisModule_OnLoad() "
7656 "symbol. Module not loaded.",path);
7657 return C_ERR;
7658 }
7659 if (onload((void*)&ctx,module_argv,module_argc) == REDISMODULE_ERR) {
7660 if (ctx.module) {
7661 moduleUnregisterCommands(ctx.module);
7662 moduleUnregisterSharedAPI(ctx.module);
7663 moduleUnregisterUsedAPI(ctx.module);
7664 moduleFreeModuleStructure(ctx.module);
7665 }
7666 dlclose(handle);
7667 serverLog(LL_WARNING,
7668 "Module %s initialization failed. Module not loaded",path);
7669 return C_ERR;
7670 }
7671
7672 /* Redis module loaded! Register it. */
7673 dictAdd(modules,ctx.module->name,ctx.module);
7674 ctx.module->blocked_clients = 0;
7675 ctx.module->handle = handle;
7676 serverLog(LL_NOTICE,"Module '%s' loaded from %s",ctx.module->name,path);
7677 /* Fire the loaded modules event. */
7678 moduleFireServerEvent(REDISMODULE_EVENT_MODULE_CHANGE,
7679 REDISMODULE_SUBEVENT_MODULE_LOADED,
7680 ctx.module);
7681
7682 moduleFreeContext(&ctx);
7683 return C_OK;
7684 }
7685
7686
7687 /* Unload the module registered with the specified name. On success
7688 * C_OK is returned, otherwise C_ERR is returned and errno is set
7689 * to the following values depending on the type of error:
7690 *
7691 * * ENONET: No such module having the specified name.
7692 * * EBUSY: The module exports a new data type and can only be reloaded. */
moduleUnload(sds name)7693 int moduleUnload(sds name) {
7694 struct RedisModule *module = dictFetchValue(modules,name);
7695
7696 if (module == NULL) {
7697 errno = ENOENT;
7698 return REDISMODULE_ERR;
7699 } else if (listLength(module->types)) {
7700 errno = EBUSY;
7701 return REDISMODULE_ERR;
7702 } else if (listLength(module->usedby)) {
7703 errno = EPERM;
7704 return REDISMODULE_ERR;
7705 } else if (module->blocked_clients) {
7706 errno = EAGAIN;
7707 return REDISMODULE_ERR;
7708 }
7709
7710 /* Give module a chance to clean up. */
7711 int (*onunload)(void *);
7712 onunload = (int (*)(void *))(unsigned long) dlsym(module->handle, "RedisModule_OnUnload");
7713 if (onunload) {
7714 RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
7715 ctx.module = module;
7716 ctx.client = moduleFreeContextReusedClient;
7717 int unload_status = onunload((void*)&ctx);
7718 moduleFreeContext(&ctx);
7719
7720 if (unload_status == REDISMODULE_ERR) {
7721 serverLog(LL_WARNING, "Module %s OnUnload failed. Unload canceled.", name);
7722 errno = ECANCELED;
7723 return REDISMODULE_ERR;
7724 }
7725 }
7726
7727 moduleFreeAuthenticatedClients(module);
7728 moduleUnregisterCommands(module);
7729 moduleUnregisterSharedAPI(module);
7730 moduleUnregisterUsedAPI(module);
7731 moduleUnregisterFilters(module);
7732
7733 /* Remove any notification subscribers this module might have */
7734 moduleUnsubscribeNotifications(module);
7735 moduleUnsubscribeAllServerEvents(module);
7736
7737 /* Unload the dynamic library. */
7738 if (dlclose(module->handle) == -1) {
7739 char *error = dlerror();
7740 if (error == NULL) error = "Unknown error";
7741 serverLog(LL_WARNING,"Error when trying to close the %s module: %s",
7742 module->name, error);
7743 }
7744
7745 /* Fire the unloaded modules event. */
7746 moduleFireServerEvent(REDISMODULE_EVENT_MODULE_CHANGE,
7747 REDISMODULE_SUBEVENT_MODULE_UNLOADED,
7748 module);
7749
7750 /* Remove from list of modules. */
7751 serverLog(LL_NOTICE,"Module %s unloaded",module->name);
7752 dictDelete(modules,module->name);
7753 module->name = NULL; /* The name was already freed by dictDelete(). */
7754 moduleFreeModuleStructure(module);
7755
7756 return REDISMODULE_OK;
7757 }
7758
7759 /* Helper function for the MODULE and HELLO command: send the list of the
7760 * loaded modules to the client. */
addReplyLoadedModules(client * c)7761 void addReplyLoadedModules(client *c) {
7762 dictIterator *di = dictGetIterator(modules);
7763 dictEntry *de;
7764
7765 addReplyArrayLen(c,dictSize(modules));
7766 while ((de = dictNext(di)) != NULL) {
7767 sds name = dictGetKey(de);
7768 struct RedisModule *module = dictGetVal(de);
7769 addReplyMapLen(c,2);
7770 addReplyBulkCString(c,"name");
7771 addReplyBulkCBuffer(c,name,sdslen(name));
7772 addReplyBulkCString(c,"ver");
7773 addReplyLongLong(c,module->ver);
7774 }
7775 dictReleaseIterator(di);
7776 }
7777
7778 /* Helper for genModulesInfoString(): given a list of modules, return
7779 * am SDS string in the form "[modulename|modulename2|...]" */
genModulesInfoStringRenderModulesList(list * l)7780 sds genModulesInfoStringRenderModulesList(list *l) {
7781 listIter li;
7782 listNode *ln;
7783 listRewind(l,&li);
7784 sds output = sdsnew("[");
7785 while((ln = listNext(&li))) {
7786 RedisModule *module = ln->value;
7787 output = sdscat(output,module->name);
7788 if (ln != listLast(l))
7789 output = sdscat(output,"|");
7790 }
7791 output = sdscat(output,"]");
7792 return output;
7793 }
7794
7795 /* Helper for genModulesInfoString(): render module options as an SDS string. */
genModulesInfoStringRenderModuleOptions(struct RedisModule * module)7796 sds genModulesInfoStringRenderModuleOptions(struct RedisModule *module) {
7797 sds output = sdsnew("[");
7798 if (module->options & REDISMODULE_OPTIONS_HANDLE_IO_ERRORS)
7799 output = sdscat(output,"handle-io-errors|");
7800 output = sdstrim(output,"|");
7801 output = sdscat(output,"]");
7802 return output;
7803 }
7804
7805
7806 /* Helper function for the INFO command: adds loaded modules as to info's
7807 * output.
7808 *
7809 * After the call, the passed sds info string is no longer valid and all the
7810 * references must be substituted with the new pointer returned by the call. */
genModulesInfoString(sds info)7811 sds genModulesInfoString(sds info) {
7812 dictIterator *di = dictGetIterator(modules);
7813 dictEntry *de;
7814
7815 while ((de = dictNext(di)) != NULL) {
7816 sds name = dictGetKey(de);
7817 struct RedisModule *module = dictGetVal(de);
7818
7819 sds usedby = genModulesInfoStringRenderModulesList(module->usedby);
7820 sds using = genModulesInfoStringRenderModulesList(module->using);
7821 sds options = genModulesInfoStringRenderModuleOptions(module);
7822 info = sdscatfmt(info,
7823 "module:name=%S,ver=%i,api=%i,filters=%i,"
7824 "usedby=%S,using=%S,options=%S\r\n",
7825 name, module->ver, module->apiver,
7826 (int)listLength(module->filters), usedby, using, options);
7827 sdsfree(usedby);
7828 sdsfree(using);
7829 sdsfree(options);
7830 }
7831 dictReleaseIterator(di);
7832 return info;
7833 }
7834
7835 /* Redis MODULE command.
7836 *
7837 * MODULE LOAD <path> [args...] */
moduleCommand(client * c)7838 void moduleCommand(client *c) {
7839 char *subcmd = c->argv[1]->ptr;
7840 if (c->argc == 2 && !strcasecmp(subcmd,"help")) {
7841 const char *help[] = {
7842 "LIST -- Return a list of loaded modules.",
7843 "LOAD <path> [arg ...] -- Load a module library from <path>.",
7844 "UNLOAD <name> -- Unload a module.",
7845 NULL
7846 };
7847 addReplyHelp(c, help);
7848 } else
7849 if (!strcasecmp(subcmd,"load") && c->argc >= 3) {
7850 robj **argv = NULL;
7851 int argc = 0;
7852
7853 if (c->argc > 3) {
7854 argc = c->argc - 3;
7855 argv = &c->argv[3];
7856 }
7857
7858 if (moduleLoad(c->argv[2]->ptr,(void **)argv,argc) == C_OK)
7859 addReply(c,shared.ok);
7860 else
7861 addReplyError(c,
7862 "Error loading the extension. Please check the server logs.");
7863 } else if (!strcasecmp(subcmd,"unload") && c->argc == 3) {
7864 if (moduleUnload(c->argv[2]->ptr) == C_OK)
7865 addReply(c,shared.ok);
7866 else {
7867 char *errmsg;
7868 switch(errno) {
7869 case ENOENT:
7870 errmsg = "no such module with that name";
7871 break;
7872 case EBUSY:
7873 errmsg = "the module exports one or more module-side data "
7874 "types, can't unload";
7875 break;
7876 case EPERM:
7877 errmsg = "the module exports APIs used by other modules. "
7878 "Please unload them first and try again";
7879 break;
7880 case EAGAIN:
7881 errmsg = "the module has blocked clients. "
7882 "Please wait them unblocked and try again";
7883 break;
7884 default:
7885 errmsg = "operation not possible.";
7886 break;
7887 }
7888 addReplyErrorFormat(c,"Error unloading module: %s",errmsg);
7889 }
7890 } else if (!strcasecmp(subcmd,"list") && c->argc == 2) {
7891 addReplyLoadedModules(c);
7892 } else {
7893 addReplySubcommandSyntaxError(c);
7894 return;
7895 }
7896 }
7897
7898 /* Return the number of registered modules. */
moduleCount(void)7899 size_t moduleCount(void) {
7900 return dictSize(modules);
7901 }
7902
7903 /* Set the key last access time for LRU based eviction. not relevant if the
7904 * servers's maxmemory policy is LFU based. Value is idle time in milliseconds.
7905 * returns REDISMODULE_OK if the LRU was updated, REDISMODULE_ERR otherwise. */
RM_SetLRU(RedisModuleKey * key,mstime_t lru_idle)7906 int RM_SetLRU(RedisModuleKey *key, mstime_t lru_idle) {
7907 if (!key->value)
7908 return REDISMODULE_ERR;
7909 if (objectSetLRUOrLFU(key->value, -1, lru_idle, lru_idle>=0 ? LRU_CLOCK() : 0, 1))
7910 return REDISMODULE_OK;
7911 return REDISMODULE_ERR;
7912 }
7913
7914 /* Gets the key last access time.
7915 * Value is idletime in milliseconds or -1 if the server's eviction policy is
7916 * LFU based.
7917 * returns REDISMODULE_OK if when key is valid. */
RM_GetLRU(RedisModuleKey * key,mstime_t * lru_idle)7918 int RM_GetLRU(RedisModuleKey *key, mstime_t *lru_idle) {
7919 *lru_idle = -1;
7920 if (!key->value)
7921 return REDISMODULE_ERR;
7922 if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU)
7923 return REDISMODULE_OK;
7924 *lru_idle = estimateObjectIdleTime(key->value);
7925 return REDISMODULE_OK;
7926 }
7927
7928 /* Set the key access frequency. only relevant if the server's maxmemory policy
7929 * is LFU based.
7930 * The frequency is a logarithmic counter that provides an indication of
7931 * the access frequencyonly (must be <= 255).
7932 * returns REDISMODULE_OK if the LFU was updated, REDISMODULE_ERR otherwise. */
RM_SetLFU(RedisModuleKey * key,long long lfu_freq)7933 int RM_SetLFU(RedisModuleKey *key, long long lfu_freq) {
7934 if (!key->value)
7935 return REDISMODULE_ERR;
7936 if (objectSetLRUOrLFU(key->value, lfu_freq, -1, 0, 1))
7937 return REDISMODULE_OK;
7938 return REDISMODULE_ERR;
7939 }
7940
7941 /* Gets the key access frequency or -1 if the server's eviction policy is not
7942 * LFU based.
7943 * returns REDISMODULE_OK if when key is valid. */
RM_GetLFU(RedisModuleKey * key,long long * lfu_freq)7944 int RM_GetLFU(RedisModuleKey *key, long long *lfu_freq) {
7945 *lfu_freq = -1;
7946 if (!key->value)
7947 return REDISMODULE_ERR;
7948 if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU)
7949 *lfu_freq = LFUDecrAndReturn(key->value);
7950 return REDISMODULE_OK;
7951 }
7952
7953 /**
7954 * Returns the full ContextFlags mask, using the return value
7955 * the module can check if a certain set of flags are supported
7956 * by the redis server version in use.
7957 * Example:
7958 * int supportedFlags = RM_GetContextFlagsAll()
7959 * if (supportedFlags & REDISMODULE_CTX_FLAGS_MULTI) {
7960 * // REDISMODULE_CTX_FLAGS_MULTI is supported
7961 * } else{
7962 * // REDISMODULE_CTX_FLAGS_MULTI is not supported
7963 * }
7964 */
RM_GetContextFlagsAll()7965 int RM_GetContextFlagsAll() {
7966 return _REDISMODULE_CTX_FLAGS_NEXT - 1;
7967 }
7968
7969 /**
7970 * Returns the full KeyspaceNotification mask, using the return value
7971 * the module can check if a certain set of flags are supported
7972 * by the redis server version in use.
7973 * Example:
7974 * int supportedFlags = RM_GetKeyspaceNotificationFlagsAll()
7975 * if (supportedFlags & REDISMODULE_NOTIFY_LOADED) {
7976 * // REDISMODULE_NOTIFY_LOADED is supported
7977 * } else{
7978 * // REDISMODULE_NOTIFY_LOADED is not supported
7979 * }
7980 */
RM_GetKeyspaceNotificationFlagsAll()7981 int RM_GetKeyspaceNotificationFlagsAll() {
7982 return _REDISMODULE_NOTIFY_NEXT - 1;
7983 }
7984
7985 /**
7986 * Return the redis version in format of 0x00MMmmpp.
7987 * Example for 6.0.7 the return value will be 0x00060007.
7988 */
RM_GetServerVersion()7989 int RM_GetServerVersion() {
7990 return REDIS_VERSION_NUM;
7991 }
7992
7993 /* Replace the value assigned to a module type.
7994 *
7995 * The key must be open for writing, have an existing value, and have a moduleType
7996 * that matches the one specified by the caller.
7997 *
7998 * Unlike RM_ModuleTypeSetValue() which will free the old value, this function
7999 * simply swaps the old value with the new value.
8000 *
8001 * The function returns REDISMODULE_OK on success, REDISMODULE_ERR on errors
8002 * such as:
8003 *
8004 * 1. Key is not opened for writing.
8005 * 2. Key is not a module data type key.
8006 * 3. Key is a module datatype other than 'mt'.
8007 *
8008 * If old_value is non-NULL, the old value is returned by reference.
8009 */
RM_ModuleTypeReplaceValue(RedisModuleKey * key,moduleType * mt,void * new_value,void ** old_value)8010 int RM_ModuleTypeReplaceValue(RedisModuleKey *key, moduleType *mt, void *new_value, void **old_value) {
8011 if (!(key->mode & REDISMODULE_WRITE) || key->iter)
8012 return REDISMODULE_ERR;
8013 if (!key->value || key->value->type != OBJ_MODULE)
8014 return REDISMODULE_ERR;
8015
8016 moduleValue *mv = key->value->ptr;
8017 if (mv->type != mt)
8018 return REDISMODULE_ERR;
8019
8020 if (old_value)
8021 *old_value = mv->value;
8022 mv->value = new_value;
8023
8024 return REDISMODULE_OK;
8025 }
8026
8027 /* For a specified command, parse its arguments and return an array that
8028 * contains the indexes of all key name arguments. This function is
8029 * essnetially a more efficient way to do COMMAND GETKEYS.
8030 *
8031 * A NULL return value indicates the specified command has no keys, or
8032 * an error condition. Error conditions are indicated by setting errno
8033 * as folllows:
8034 *
8035 * ENOENT: Specified command does not exist.
8036 * EINVAL: Invalid command arity specified.
8037 *
8038 * NOTE: The returned array is not a Redis Module object so it does not
8039 * get automatically freed even when auto-memory is used. The caller
8040 * must explicitly call RM_Free() to free it.
8041 */
RM_GetCommandKeys(RedisModuleCtx * ctx,RedisModuleString ** argv,int argc,int * num_keys)8042 int *RM_GetCommandKeys(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int *num_keys) {
8043 UNUSED(ctx);
8044 struct redisCommand *cmd;
8045 int *res = NULL;
8046
8047 /* Find command */
8048 if ((cmd = lookupCommand(argv[0]->ptr)) == NULL) {
8049 errno = ENOENT;
8050 return NULL;
8051 }
8052
8053 /* Bail out if command has no keys */
8054 if (cmd->getkeys_proc == NULL && cmd->firstkey == 0) {
8055 errno = 0;
8056 return NULL;
8057 }
8058
8059 if ((cmd->arity > 0 && cmd->arity != argc) || (argc < -cmd->arity)) {
8060 errno = EINVAL;
8061 return NULL;
8062 }
8063
8064 getKeysResult result = GETKEYS_RESULT_INIT;
8065 getKeysFromCommand(cmd, argv, argc, &result);
8066
8067 *num_keys = result.numkeys;
8068 if (!result.numkeys) {
8069 errno = 0;
8070 getKeysFreeResult(&result);
8071 return NULL;
8072 }
8073
8074 if (result.keys == result.keysbuf) {
8075 /* If the result is using a stack based array, copy it. */
8076 unsigned long int size = sizeof(int) * result.numkeys;
8077 res = zmalloc(size);
8078 memcpy(res, result.keys, size);
8079 } else {
8080 /* We return the heap based array and intentionally avoid calling
8081 * getKeysFreeResult() here, as it is the caller's responsibility
8082 * to free this array.
8083 */
8084 res = result.keys;
8085 }
8086
8087 return res;
8088 }
8089
8090 /* Register all the APIs we export. Keep this function at the end of the
8091 * file so that's easy to seek it to add new entries. */
moduleRegisterCoreAPI(void)8092 void moduleRegisterCoreAPI(void) {
8093 server.moduleapi = dictCreate(&moduleAPIDictType,NULL);
8094 server.sharedapi = dictCreate(&moduleAPIDictType,NULL);
8095 REGISTER_API(Alloc);
8096 REGISTER_API(Calloc);
8097 REGISTER_API(Realloc);
8098 REGISTER_API(Free);
8099 REGISTER_API(Strdup);
8100 REGISTER_API(CreateCommand);
8101 REGISTER_API(SetModuleAttribs);
8102 REGISTER_API(IsModuleNameBusy);
8103 REGISTER_API(WrongArity);
8104 REGISTER_API(ReplyWithLongLong);
8105 REGISTER_API(ReplyWithError);
8106 REGISTER_API(ReplyWithSimpleString);
8107 REGISTER_API(ReplyWithArray);
8108 REGISTER_API(ReplyWithNullArray);
8109 REGISTER_API(ReplyWithEmptyArray);
8110 REGISTER_API(ReplySetArrayLength);
8111 REGISTER_API(ReplyWithString);
8112 REGISTER_API(ReplyWithEmptyString);
8113 REGISTER_API(ReplyWithVerbatimString);
8114 REGISTER_API(ReplyWithStringBuffer);
8115 REGISTER_API(ReplyWithCString);
8116 REGISTER_API(ReplyWithNull);
8117 REGISTER_API(ReplyWithCallReply);
8118 REGISTER_API(ReplyWithDouble);
8119 REGISTER_API(ReplyWithLongDouble);
8120 REGISTER_API(GetSelectedDb);
8121 REGISTER_API(SelectDb);
8122 REGISTER_API(OpenKey);
8123 REGISTER_API(CloseKey);
8124 REGISTER_API(KeyType);
8125 REGISTER_API(ValueLength);
8126 REGISTER_API(ListPush);
8127 REGISTER_API(ListPop);
8128 REGISTER_API(StringToLongLong);
8129 REGISTER_API(StringToDouble);
8130 REGISTER_API(StringToLongDouble);
8131 REGISTER_API(Call);
8132 REGISTER_API(CallReplyProto);
8133 REGISTER_API(FreeCallReply);
8134 REGISTER_API(CallReplyInteger);
8135 REGISTER_API(CallReplyType);
8136 REGISTER_API(CallReplyLength);
8137 REGISTER_API(CallReplyArrayElement);
8138 REGISTER_API(CallReplyStringPtr);
8139 REGISTER_API(CreateStringFromCallReply);
8140 REGISTER_API(CreateString);
8141 REGISTER_API(CreateStringFromLongLong);
8142 REGISTER_API(CreateStringFromDouble);
8143 REGISTER_API(CreateStringFromLongDouble);
8144 REGISTER_API(CreateStringFromString);
8145 REGISTER_API(CreateStringPrintf);
8146 REGISTER_API(FreeString);
8147 REGISTER_API(StringPtrLen);
8148 REGISTER_API(AutoMemory);
8149 REGISTER_API(Replicate);
8150 REGISTER_API(ReplicateVerbatim);
8151 REGISTER_API(DeleteKey);
8152 REGISTER_API(UnlinkKey);
8153 REGISTER_API(StringSet);
8154 REGISTER_API(StringDMA);
8155 REGISTER_API(StringTruncate);
8156 REGISTER_API(SetExpire);
8157 REGISTER_API(GetExpire);
8158 REGISTER_API(ResetDataset);
8159 REGISTER_API(DbSize);
8160 REGISTER_API(RandomKey);
8161 REGISTER_API(ZsetAdd);
8162 REGISTER_API(ZsetIncrby);
8163 REGISTER_API(ZsetScore);
8164 REGISTER_API(ZsetRem);
8165 REGISTER_API(ZsetRangeStop);
8166 REGISTER_API(ZsetFirstInScoreRange);
8167 REGISTER_API(ZsetLastInScoreRange);
8168 REGISTER_API(ZsetFirstInLexRange);
8169 REGISTER_API(ZsetLastInLexRange);
8170 REGISTER_API(ZsetRangeCurrentElement);
8171 REGISTER_API(ZsetRangeNext);
8172 REGISTER_API(ZsetRangePrev);
8173 REGISTER_API(ZsetRangeEndReached);
8174 REGISTER_API(HashSet);
8175 REGISTER_API(HashGet);
8176 REGISTER_API(IsKeysPositionRequest);
8177 REGISTER_API(KeyAtPos);
8178 REGISTER_API(GetClientId);
8179 REGISTER_API(GetContextFlags);
8180 REGISTER_API(AvoidReplicaTraffic);
8181 REGISTER_API(PoolAlloc);
8182 REGISTER_API(CreateDataType);
8183 REGISTER_API(ModuleTypeSetValue);
8184 REGISTER_API(ModuleTypeReplaceValue);
8185 REGISTER_API(ModuleTypeGetType);
8186 REGISTER_API(ModuleTypeGetValue);
8187 REGISTER_API(IsIOError);
8188 REGISTER_API(SetModuleOptions);
8189 REGISTER_API(SignalModifiedKey);
8190 REGISTER_API(SaveUnsigned);
8191 REGISTER_API(LoadUnsigned);
8192 REGISTER_API(SaveSigned);
8193 REGISTER_API(LoadSigned);
8194 REGISTER_API(SaveString);
8195 REGISTER_API(SaveStringBuffer);
8196 REGISTER_API(LoadString);
8197 REGISTER_API(LoadStringBuffer);
8198 REGISTER_API(SaveDouble);
8199 REGISTER_API(LoadDouble);
8200 REGISTER_API(SaveFloat);
8201 REGISTER_API(LoadFloat);
8202 REGISTER_API(SaveLongDouble);
8203 REGISTER_API(LoadLongDouble);
8204 REGISTER_API(SaveDataTypeToString);
8205 REGISTER_API(LoadDataTypeFromString);
8206 REGISTER_API(EmitAOF);
8207 REGISTER_API(Log);
8208 REGISTER_API(LogIOError);
8209 REGISTER_API(_Assert);
8210 REGISTER_API(LatencyAddSample);
8211 REGISTER_API(StringAppendBuffer);
8212 REGISTER_API(RetainString);
8213 REGISTER_API(HoldString);
8214 REGISTER_API(StringCompare);
8215 REGISTER_API(GetContextFromIO);
8216 REGISTER_API(GetKeyNameFromIO);
8217 REGISTER_API(GetKeyNameFromModuleKey);
8218 REGISTER_API(BlockClient);
8219 REGISTER_API(UnblockClient);
8220 REGISTER_API(IsBlockedReplyRequest);
8221 REGISTER_API(IsBlockedTimeoutRequest);
8222 REGISTER_API(GetBlockedClientPrivateData);
8223 REGISTER_API(AbortBlock);
8224 REGISTER_API(Milliseconds);
8225 REGISTER_API(GetThreadSafeContext);
8226 REGISTER_API(GetDetachedThreadSafeContext);
8227 REGISTER_API(FreeThreadSafeContext);
8228 REGISTER_API(ThreadSafeContextLock);
8229 REGISTER_API(ThreadSafeContextTryLock);
8230 REGISTER_API(ThreadSafeContextUnlock);
8231 REGISTER_API(DigestAddStringBuffer);
8232 REGISTER_API(DigestAddLongLong);
8233 REGISTER_API(DigestEndSequence);
8234 REGISTER_API(NotifyKeyspaceEvent);
8235 REGISTER_API(GetNotifyKeyspaceEvents);
8236 REGISTER_API(SubscribeToKeyspaceEvents);
8237 REGISTER_API(RegisterClusterMessageReceiver);
8238 REGISTER_API(SendClusterMessage);
8239 REGISTER_API(GetClusterNodeInfo);
8240 REGISTER_API(GetClusterNodesList);
8241 REGISTER_API(FreeClusterNodesList);
8242 REGISTER_API(CreateTimer);
8243 REGISTER_API(StopTimer);
8244 REGISTER_API(GetTimerInfo);
8245 REGISTER_API(GetMyClusterID);
8246 REGISTER_API(GetClusterSize);
8247 REGISTER_API(GetRandomBytes);
8248 REGISTER_API(GetRandomHexChars);
8249 REGISTER_API(BlockedClientDisconnected);
8250 REGISTER_API(SetDisconnectCallback);
8251 REGISTER_API(GetBlockedClientHandle);
8252 REGISTER_API(SetClusterFlags);
8253 REGISTER_API(CreateDict);
8254 REGISTER_API(FreeDict);
8255 REGISTER_API(DictSize);
8256 REGISTER_API(DictSetC);
8257 REGISTER_API(DictReplaceC);
8258 REGISTER_API(DictSet);
8259 REGISTER_API(DictReplace);
8260 REGISTER_API(DictGetC);
8261 REGISTER_API(DictGet);
8262 REGISTER_API(DictDelC);
8263 REGISTER_API(DictDel);
8264 REGISTER_API(DictIteratorStartC);
8265 REGISTER_API(DictIteratorStart);
8266 REGISTER_API(DictIteratorStop);
8267 REGISTER_API(DictIteratorReseekC);
8268 REGISTER_API(DictIteratorReseek);
8269 REGISTER_API(DictNextC);
8270 REGISTER_API(DictPrevC);
8271 REGISTER_API(DictNext);
8272 REGISTER_API(DictPrev);
8273 REGISTER_API(DictCompareC);
8274 REGISTER_API(DictCompare);
8275 REGISTER_API(ExportSharedAPI);
8276 REGISTER_API(GetSharedAPI);
8277 REGISTER_API(RegisterCommandFilter);
8278 REGISTER_API(UnregisterCommandFilter);
8279 REGISTER_API(CommandFilterArgsCount);
8280 REGISTER_API(CommandFilterArgGet);
8281 REGISTER_API(CommandFilterArgInsert);
8282 REGISTER_API(CommandFilterArgReplace);
8283 REGISTER_API(CommandFilterArgDelete);
8284 REGISTER_API(Fork);
8285 REGISTER_API(ExitFromChild);
8286 REGISTER_API(KillForkChild);
8287 REGISTER_API(RegisterInfoFunc);
8288 REGISTER_API(InfoAddSection);
8289 REGISTER_API(InfoBeginDictField);
8290 REGISTER_API(InfoEndDictField);
8291 REGISTER_API(InfoAddFieldString);
8292 REGISTER_API(InfoAddFieldCString);
8293 REGISTER_API(InfoAddFieldDouble);
8294 REGISTER_API(InfoAddFieldLongLong);
8295 REGISTER_API(InfoAddFieldULongLong);
8296 REGISTER_API(GetServerInfo);
8297 REGISTER_API(FreeServerInfo);
8298 REGISTER_API(ServerInfoGetField);
8299 REGISTER_API(ServerInfoGetFieldC);
8300 REGISTER_API(ServerInfoGetFieldSigned);
8301 REGISTER_API(ServerInfoGetFieldUnsigned);
8302 REGISTER_API(ServerInfoGetFieldDouble);
8303 REGISTER_API(GetClientInfoById);
8304 REGISTER_API(PublishMessage);
8305 REGISTER_API(SubscribeToServerEvent);
8306 REGISTER_API(SetLRU);
8307 REGISTER_API(GetLRU);
8308 REGISTER_API(SetLFU);
8309 REGISTER_API(GetLFU);
8310 REGISTER_API(BlockClientOnKeys);
8311 REGISTER_API(SignalKeyAsReady);
8312 REGISTER_API(GetBlockedClientReadyKey);
8313 REGISTER_API(GetUsedMemoryRatio);
8314 REGISTER_API(MallocSize);
8315 REGISTER_API(ScanCursorCreate);
8316 REGISTER_API(ScanCursorDestroy);
8317 REGISTER_API(ScanCursorRestart);
8318 REGISTER_API(Scan);
8319 REGISTER_API(ScanKey);
8320 REGISTER_API(CreateModuleUser);
8321 REGISTER_API(SetModuleUserACL);
8322 REGISTER_API(FreeModuleUser);
8323 REGISTER_API(DeauthenticateAndCloseClient);
8324 REGISTER_API(AuthenticateClientWithACLUser);
8325 REGISTER_API(AuthenticateClientWithUser);
8326 REGISTER_API(GetContextFlagsAll);
8327 REGISTER_API(GetKeyspaceNotificationFlagsAll);
8328 REGISTER_API(IsSubEventSupported);
8329 REGISTER_API(GetServerVersion);
8330 REGISTER_API(GetClientCertificate);
8331 REGISTER_API(GetCommandKeys);
8332 }
8333