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/* --------------------------------------------------------------------------
31 * Modules API documentation information
32 *
33 * The comments in this file are used to generate the API documentation on the
34 * Redis website.
35 *
36 * Each function starting with RM_ and preceded by a block comment is included
37 * in the API documentation. To hide an RM_ function, put a blank line between
38 * the comment and the function definition or put the comment inside the
39 * function body.
40 *
41 * The functions are divided into sections. Each section is preceded by a
42 * documentation block, which is comment block starting with a markdown level 2
43 * heading, i.e. a line starting with ##, on the first line of the comment block
44 * (with the exception of a ----- line which can appear first). Other comment
45 * blocks, which are not intended for the modules API user, such as this comment
46 * block, do NOT start with a markdown level 2 heading, so they are included in
47 * the generated a API documentation.
48 *
49 * The documentation comments may contain markdown formatting. Some automatic
50 * replacements are done, such as the replacement of RM with RedisModule in
51 * function names. For details, see the script src/modules/gendoc.rb.
52 * -------------------------------------------------------------------------- */
53
54#include "server.h"
55#include "cluster.h"
56#include "slowlog.h"
57#include "rdb.h"
58#include "monotonic.h"
59#include "script.h"
60#include "call_reply.h"
61#include <dlfcn.h>
62#include <sys/stat.h>
63#include <sys/wait.h>
64#include <fcntl.h>
65
66/* --------------------------------------------------------------------------
67 * Private data structures used by the modules system. Those are data
68 * structures that are never exposed to Redis Modules, if not as void
69 * pointers that have an API the module can call with them)
70 * -------------------------------------------------------------------------- */
71
72typedef struct RedisModuleInfoCtx {
73 struct RedisModule *module;
74 dict *requested_sections;
75 sds info; /* info string we collected so far */
76 int sections; /* number of sections we collected so far */
77 int in_section; /* indication if we're in an active section or not */
78 int in_dict_field; /* indication that we're currently appending to a dict */
79} RedisModuleInfoCtx;
80
81/* This represents a shared API. Shared APIs will be used to populate
82 * the server.sharedapi dictionary, mapping names of APIs exported by
83 * modules for other modules to use, to their structure specifying the
84 * function pointer that can be called. */
85struct RedisModuleSharedAPI {
86 void *func;
87 RedisModule *module;
88};
89typedef struct RedisModuleSharedAPI RedisModuleSharedAPI;
90
91dict *modules; /* Hash table of modules. SDS -> RedisModule ptr.*/
92
93/* Entries in the context->amqueue array, representing objects to free
94 * when the callback returns. */
95struct AutoMemEntry {
96 void *ptr;
97 int type;
98};
99
100/* AutoMemEntry type field values. */
101#define REDISMODULE_AM_KEY 0
102#define REDISMODULE_AM_STRING 1
103#define REDISMODULE_AM_REPLY 2
104#define REDISMODULE_AM_FREED 3 /* Explicitly freed by user already. */
105#define REDISMODULE_AM_DICT 4
106#define REDISMODULE_AM_INFO 5
107
108/* The pool allocator block. Redis Modules can allocate memory via this special
109 * allocator that will automatically release it all once the callback returns.
110 * This means that it can only be used for ephemeral allocations. However
111 * there are two advantages for modules to use this API:
112 *
113 * 1) The memory is automatically released when the callback returns.
114 * 2) This allocator is faster for many small allocations since whole blocks
115 * are allocated, and small pieces returned to the caller just advancing
116 * the index of the allocation.
117 *
118 * Allocations are always rounded to the size of the void pointer in order
119 * to always return aligned memory chunks. */
120
121#define REDISMODULE_POOL_ALLOC_MIN_SIZE (1024*8)
122#define REDISMODULE_POOL_ALLOC_ALIGN (sizeof(void*))
123
124typedef struct RedisModulePoolAllocBlock {
125 uint32_t size;
126 uint32_t used;
127 struct RedisModulePoolAllocBlock *next;
128 char memory[];
129} RedisModulePoolAllocBlock;
130
131/* This structure represents the context in which Redis modules operate.
132 * Most APIs module can access, get a pointer to the context, so that the API
133 * implementation can hold state across calls, or remember what to free after
134 * the call and so forth.
135 *
136 * Note that not all the context structure is always filled with actual values
137 * but only the fields needed in a given context. */
138
139struct RedisModuleBlockedClient;
140
141struct RedisModuleCtx {
142 void *getapifuncptr; /* NOTE: Must be the first field. */
143 struct RedisModule *module; /* Module reference. */
144 client *client; /* Client calling a command. */
145 struct RedisModuleBlockedClient *blocked_client; /* Blocked client for
146 thread safe context. */
147 struct AutoMemEntry *amqueue; /* Auto memory queue of objects to free. */
148 int amqueue_len; /* Number of slots in amqueue. */
149 int amqueue_used; /* Number of used slots in amqueue. */
150 int flags; /* REDISMODULE_CTX_... flags. */
151 void **postponed_arrays; /* To set with RM_ReplySetArrayLength(). */
152 int postponed_arrays_count; /* Number of entries in postponed_arrays. */
153 void *blocked_privdata; /* Privdata set when unblocking a client. */
154 RedisModuleString *blocked_ready_key; /* Key ready when the reply callback
155 gets called for clients blocked
156 on keys. */
157
158 /* Used if there is the REDISMODULE_CTX_KEYS_POS_REQUEST or
159 * REDISMODULE_CTX_CHANNEL_POS_REQUEST flag set. */
160 getKeysResult *keys_result;
161
162 struct RedisModulePoolAllocBlock *pa_head;
163 long long next_yield_time;
164};
165typedef struct RedisModuleCtx RedisModuleCtx;
166
167#define REDISMODULE_CTX_NONE (0)
168#define REDISMODULE_CTX_AUTO_MEMORY (1<<0)
169#define REDISMODULE_CTX_KEYS_POS_REQUEST (1<<1)
170#define REDISMODULE_CTX_BLOCKED_REPLY (1<<2)
171#define REDISMODULE_CTX_BLOCKED_TIMEOUT (1<<3)
172#define REDISMODULE_CTX_THREAD_SAFE (1<<4)
173#define REDISMODULE_CTX_BLOCKED_DISCONNECTED (1<<5)
174#define REDISMODULE_CTX_TEMP_CLIENT (1<<6) /* Return client object to the pool
175 when the context is destroyed */
176#define REDISMODULE_CTX_NEW_CLIENT (1<<7) /* Free client object when the
177 context is destroyed */
178#define REDISMODULE_CTX_CHANNELS_POS_REQUEST (1<<8)
179
180/* This represents a Redis key opened with RM_OpenKey(). */
181struct RedisModuleKey {
182 RedisModuleCtx *ctx;
183 redisDb *db;
184 robj *key; /* Key name object. */
185 robj *value; /* Value object, or NULL if the key was not found. */
186 void *iter; /* Iterator. */
187 int mode; /* Opening mode. */
188
189 union {
190 struct {
191 /* List, use only if value->type == OBJ_LIST */
192 listTypeEntry entry; /* Current entry in iteration. */
193 long index; /* Current 0-based index in iteration. */
194 } list;
195 struct {
196 /* Zset iterator, use only if value->type == OBJ_ZSET */
197 uint32_t type; /* REDISMODULE_ZSET_RANGE_* */
198 zrangespec rs; /* Score range. */
199 zlexrangespec lrs; /* Lex range. */
200 uint32_t start; /* Start pos for positional ranges. */
201 uint32_t end; /* End pos for positional ranges. */
202 void *current; /* Zset iterator current node. */
203 int er; /* Zset iterator end reached flag
204 (true if end was reached). */
205 } zset;
206 struct {
207 /* Stream, use only if value->type == OBJ_STREAM */
208 streamID currentid; /* Current entry while iterating. */
209 int64_t numfieldsleft; /* Fields left to fetch for current entry. */
210 int signalready; /* Flag that signalKeyAsReady() is needed. */
211 } stream;
212 } u;
213};
214typedef struct RedisModuleKey RedisModuleKey;
215
216/* RedisModuleKey 'ztype' values. */
217#define REDISMODULE_ZSET_RANGE_NONE 0 /* This must always be 0. */
218#define REDISMODULE_ZSET_RANGE_LEX 1
219#define REDISMODULE_ZSET_RANGE_SCORE 2
220#define REDISMODULE_ZSET_RANGE_POS 3
221
222/* Function pointer type of a function representing a command inside
223 * a Redis module. */
224struct RedisModuleBlockedClient;
225typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, void **argv, int argc);
226typedef void (*RedisModuleDisconnectFunc) (RedisModuleCtx *ctx, struct RedisModuleBlockedClient *bc);
227
228/* This struct holds the information about a command registered by a module.*/
229struct RedisModuleCommand {
230 struct RedisModule *module;
231 RedisModuleCmdFunc func;
232 struct redisCommand *rediscmd;
233};
234typedef struct RedisModuleCommand RedisModuleCommand;
235
236#define REDISMODULE_REPLYFLAG_NONE 0
237#define REDISMODULE_REPLYFLAG_TOPARSE (1<<0) /* Protocol must be parsed. */
238#define REDISMODULE_REPLYFLAG_NESTED (1<<1) /* Nested reply object. No proto
239 or struct free. */
240
241/* Reply of RM_Call() function. The function is filled in a lazy
242 * way depending on the function called on the reply structure. By default
243 * only the type, proto and protolen are filled. */
244typedef struct CallReply RedisModuleCallReply;
245
246/* Structure representing a blocked client. We get a pointer to such
247 * an object when blocking from modules. */
248typedef struct RedisModuleBlockedClient {
249 client *client; /* Pointer to the blocked client. or NULL if the client
250 was destroyed during the life of this object. */
251 RedisModule *module; /* Module blocking the client. */
252 RedisModuleCmdFunc reply_callback; /* Reply callback on normal completion.*/
253 RedisModuleCmdFunc timeout_callback; /* Reply callback on timeout. */
254 RedisModuleDisconnectFunc disconnect_callback; /* Called on disconnection.*/
255 void (*free_privdata)(RedisModuleCtx*,void*);/* privdata cleanup callback.*/
256 void *privdata; /* Module private data that may be used by the reply
257 or timeout callback. It is set via the
258 RedisModule_UnblockClient() API. */
259 client *thread_safe_ctx_client; /* Fake client to be used for thread safe
260 context so that no lock is required. */
261 client *reply_client; /* Fake client used to accumulate replies
262 in thread safe contexts. */
263 int dbid; /* Database number selected by the original client. */
264 int blocked_on_keys; /* If blocked via RM_BlockClientOnKeys(). */
265 int unblocked; /* Already on the moduleUnblocked list. */
266 monotime background_timer; /* Timer tracking the start of background work */
267 uint64_t background_duration; /* Current command background time duration.
268 Used for measuring latency of blocking cmds */
269} RedisModuleBlockedClient;
270
271static pthread_mutex_t moduleUnblockedClientsMutex = PTHREAD_MUTEX_INITIALIZER;
272static list *moduleUnblockedClients;
273
274/* Pool for temporary client objects. Creating and destroying a client object is
275 * costly. We manage a pool of clients to avoid this cost. Pool expands when
276 * more clients are needed and shrinks when unused. Please see modulesCron()
277 * for more details. */
278static client **moduleTempClients;
279static size_t moduleTempClientCap = 0;
280static size_t moduleTempClientCount = 0; /* Client count in pool */
281static size_t moduleTempClientMinCount = 0; /* Min client count in pool since
282 the last cron. */
283
284/* We need a mutex that is unlocked / relocked in beforeSleep() in order to
285 * allow thread safe contexts to execute commands at a safe moment. */
286static pthread_mutex_t moduleGIL = PTHREAD_MUTEX_INITIALIZER;
287
288
289/* Function pointer type for keyspace event notification subscriptions from modules. */
290typedef int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
291
292/* Keyspace notification subscriber information.
293 * See RM_SubscribeToKeyspaceEvents() for more information. */
294typedef struct RedisModuleKeyspaceSubscriber {
295 /* The module subscribed to the event */
296 RedisModule *module;
297 /* Notification callback in the module*/
298 RedisModuleNotificationFunc notify_callback;
299 /* A bit mask of the events the module is interested in */
300 int event_mask;
301 /* Active flag set on entry, to avoid reentrant subscribers
302 * calling themselves */
303 int active;
304} RedisModuleKeyspaceSubscriber;
305
306/* The module keyspace notification subscribers list */
307static list *moduleKeyspaceSubscribers;
308
309/* Data structures related to the exported dictionary data structure. */
310typedef struct RedisModuleDict {
311 rax *rax; /* The radix tree. */
312} RedisModuleDict;
313
314typedef struct RedisModuleDictIter {
315 RedisModuleDict *dict;
316 raxIterator ri;
317} RedisModuleDictIter;
318
319typedef struct RedisModuleCommandFilterCtx {
320 RedisModuleString **argv;
321 int argc;
322} RedisModuleCommandFilterCtx;
323
324typedef void (*RedisModuleCommandFilterFunc) (RedisModuleCommandFilterCtx *filter);
325
326typedef struct RedisModuleCommandFilter {
327 /* The module that registered the filter */
328 RedisModule *module;
329 /* Filter callback function */
330 RedisModuleCommandFilterFunc callback;
331 /* REDISMODULE_CMDFILTER_* flags */
332 int flags;
333} RedisModuleCommandFilter;
334
335/* Registered filters */
336static list *moduleCommandFilters;
337
338typedef void (*RedisModuleForkDoneHandler) (int exitcode, int bysignal, void *user_data);
339
340static struct RedisModuleForkInfo {
341 RedisModuleForkDoneHandler done_handler;
342 void* done_handler_user_data;
343} moduleForkInfo = {0};
344
345typedef struct RedisModuleServerInfoData {
346 rax *rax; /* parsed info data. */
347} RedisModuleServerInfoData;
348
349/* Flags for moduleCreateArgvFromUserFormat(). */
350#define REDISMODULE_ARGV_REPLICATE (1<<0)
351#define REDISMODULE_ARGV_NO_AOF (1<<1)
352#define REDISMODULE_ARGV_NO_REPLICAS (1<<2)
353#define REDISMODULE_ARGV_RESP_3 (1<<3)
354#define REDISMODULE_ARGV_RESP_AUTO (1<<4)
355#define REDISMODULE_ARGV_CHECK_ACL (1<<5)
356#define REDISMODULE_ARGV_SCRIPT_MODE (1<<6)
357#define REDISMODULE_ARGV_NO_WRITES (1<<7)
358#define REDISMODULE_ARGV_CALL_REPLIES_AS_ERRORS (1<<8)
359#define REDISMODULE_ARGV_RESPECT_DENY_OOM (1<<9)
360
361/* Determine whether Redis should signalModifiedKey implicitly.
362 * In case 'ctx' has no 'module' member (and therefore no module->options),
363 * we assume default behavior, that is, Redis signals.
364 * (see RM_GetThreadSafeContext) */
365#define SHOULD_SIGNAL_MODIFIED_KEYS(ctx) \
366 ctx->module? !(ctx->module->options & REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED) : 1
367
368/* Server events hooks data structures and defines: this modules API
369 * allow modules to subscribe to certain events in Redis, such as
370 * the start and end of an RDB or AOF save, the change of role in replication,
371 * and similar other events. */
372
373typedef struct RedisModuleEventListener {
374 RedisModule *module;
375 RedisModuleEvent event;
376 RedisModuleEventCallback callback;
377} RedisModuleEventListener;
378
379list *RedisModule_EventListeners; /* Global list of all the active events. */
380
381/* Data structures related to the redis module users */
382
383/* This is the object returned by RM_CreateModuleUser(). The module API is
384 * able to create users, set ACLs to such users, and later authenticate
385 * clients using such newly created users. */
386typedef struct RedisModuleUser {
387 user *user; /* Reference to the real redis user */
388 int free_user; /* Indicates that user should also be freed when this object is freed */
389} RedisModuleUser;
390
391/* This is a structure used to export some meta-information such as dbid to the module. */
392typedef struct RedisModuleKeyOptCtx {
393 struct redisObject *from_key, *to_key; /* Optional name of key processed, NULL when unknown.
394 In most cases, only 'from_key' is valid, but in callbacks
395 such as `copy2`, both 'from_key' and 'to_key' are valid. */
396 int from_dbid, to_dbid; /* The dbid of the key being processed, -1 when unknown.
397 In most cases, only 'from_dbid' is valid, but in callbacks such
398 as `copy2`, 'from_dbid' and 'to_dbid' are both valid. */
399} RedisModuleKeyOptCtx;
400
401/* Data structures related to redis module configurations */
402/* The function signatures for module config get callbacks. These are identical to the ones exposed in redismodule.h. */
403typedef RedisModuleString * (*RedisModuleConfigGetStringFunc)(const char *name, void *privdata);
404typedef long long (*RedisModuleConfigGetNumericFunc)(const char *name, void *privdata);
405typedef int (*RedisModuleConfigGetBoolFunc)(const char *name, void *privdata);
406typedef int (*RedisModuleConfigGetEnumFunc)(const char *name, void *privdata);
407/* The function signatures for module config set callbacks. These are identical to the ones exposed in redismodule.h. */
408typedef int (*RedisModuleConfigSetStringFunc)(const char *name, RedisModuleString *val, void *privdata, RedisModuleString **err);
409typedef int (*RedisModuleConfigSetNumericFunc)(const char *name, long long val, void *privdata, RedisModuleString **err);
410typedef int (*RedisModuleConfigSetBoolFunc)(const char *name, int val, void *privdata, RedisModuleString **err);
411typedef int (*RedisModuleConfigSetEnumFunc)(const char *name, int val, void *privdata, RedisModuleString **err);
412/* Apply signature, identical to redismodule.h */
413typedef int (*RedisModuleConfigApplyFunc)(RedisModuleCtx *ctx, void *privdata, RedisModuleString **err);
414
415/* Struct representing a module config. These are stored in a list in the module struct */
416struct ModuleConfig {
417 sds name; /* Name of config without the module name appended to the front */
418 void *privdata; /* Optional data passed into the module config callbacks */
419 union get_fn { /* The get callback specified by the module */
420 RedisModuleConfigGetStringFunc get_string;
421 RedisModuleConfigGetNumericFunc get_numeric;
422 RedisModuleConfigGetBoolFunc get_bool;
423 RedisModuleConfigGetEnumFunc get_enum;
424 } get_fn;
425 union set_fn { /* The set callback specified by the module */
426 RedisModuleConfigSetStringFunc set_string;
427 RedisModuleConfigSetNumericFunc set_numeric;
428 RedisModuleConfigSetBoolFunc set_bool;
429 RedisModuleConfigSetEnumFunc set_enum;
430 } set_fn;
431 RedisModuleConfigApplyFunc apply_fn;
432 RedisModule *module;
433};
434
435/* --------------------------------------------------------------------------
436 * Prototypes
437 * -------------------------------------------------------------------------- */
438
439void RM_FreeCallReply(RedisModuleCallReply *reply);
440void RM_CloseKey(RedisModuleKey *key);
441void autoMemoryCollect(RedisModuleCtx *ctx);
442robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *argvlenp, int *flags, va_list ap);
443void RM_ZsetRangeStop(RedisModuleKey *kp);
444static void zsetKeyReset(RedisModuleKey *key);
445static void moduleInitKeyTypeSpecific(RedisModuleKey *key);
446void RM_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d);
447void RM_FreeServerInfo(RedisModuleCtx *ctx, RedisModuleServerInfoData *data);
448
449/* Helpers for RM_SetCommandInfo. */
450static int moduleValidateCommandInfo(const RedisModuleCommandInfo *info);
451static int64_t moduleConvertKeySpecsFlags(int64_t flags, int from_api);
452static int moduleValidateCommandArgs(RedisModuleCommandArg *args,
453 const RedisModuleCommandInfoVersion *version);
454static struct redisCommandArg *moduleCopyCommandArgs(RedisModuleCommandArg *args,
455 const RedisModuleCommandInfoVersion *version);
456static redisCommandArgType moduleConvertArgType(RedisModuleCommandArgType type, int *error);
457static int moduleConvertArgFlags(int flags);
458
459/* --------------------------------------------------------------------------
460 * ## Heap allocation raw functions
461 *
462 * Memory allocated with these functions are taken into account by Redis key
463 * eviction algorithms and are reported in Redis memory usage information.
464 * -------------------------------------------------------------------------- */
465
466/* Use like malloc(). Memory allocated with this function is reported in
467 * Redis INFO memory, used for keys eviction according to maxmemory settings
468 * and in general is taken into account as memory allocated by Redis.
469 * You should avoid using malloc().
470 * This function panics if unable to allocate enough memory. */
471void *RM_Alloc(size_t bytes) {
472 return zmalloc(bytes);
473}
474
475/* Similar to RM_Alloc, but returns NULL in case of allocation failure, instead
476 * of panicking. */
477void *RM_TryAlloc(size_t bytes) {
478 return ztrymalloc(bytes);
479}
480
481/* Use like calloc(). Memory allocated with this function is reported in
482 * Redis INFO memory, used for keys eviction according to maxmemory settings
483 * and in general is taken into account as memory allocated by Redis.
484 * You should avoid using calloc() directly. */
485void *RM_Calloc(size_t nmemb, size_t size) {
486 return zcalloc(nmemb*size);
487}
488
489/* Use like realloc() for memory obtained with RedisModule_Alloc(). */
490void* RM_Realloc(void *ptr, size_t bytes) {
491 return zrealloc(ptr,bytes);
492}
493
494/* Use like free() for memory obtained by RedisModule_Alloc() and
495 * RedisModule_Realloc(). However you should never try to free with
496 * RedisModule_Free() memory allocated with malloc() inside your module. */
497void RM_Free(void *ptr) {
498 zfree(ptr);
499}
500
501/* Like strdup() but returns memory allocated with RedisModule_Alloc(). */
502char *RM_Strdup(const char *str) {
503 return zstrdup(str);
504}
505
506/* --------------------------------------------------------------------------
507 * Pool allocator
508 * -------------------------------------------------------------------------- */
509
510/* Release the chain of blocks used for pool allocations. */
511void poolAllocRelease(RedisModuleCtx *ctx) {
512 RedisModulePoolAllocBlock *head = ctx->pa_head, *next;
513
514 while(head != NULL) {
515 next = head->next;
516 zfree(head);
517 head = next;
518 }
519 ctx->pa_head = NULL;
520}
521
522/* Return heap allocated memory that will be freed automatically when the
523 * module callback function returns. Mostly suitable for small allocations
524 * that are short living and must be released when the callback returns
525 * anyway. The returned memory is aligned to the architecture word size
526 * if at least word size bytes are requested, otherwise it is just
527 * aligned to the next power of two, so for example a 3 bytes request is
528 * 4 bytes aligned while a 2 bytes request is 2 bytes aligned.
529 *
530 * There is no realloc style function since when this is needed to use the
531 * pool allocator is not a good idea.
532 *
533 * The function returns NULL if `bytes` is 0. */
534void *RM_PoolAlloc(RedisModuleCtx *ctx, size_t bytes) {
535 if (bytes == 0) return NULL;
536 RedisModulePoolAllocBlock *b = ctx->pa_head;
537 size_t left = b ? b->size - b->used : 0;
538
539 /* Fix alignment. */
540 if (left >= bytes) {
541 size_t alignment = REDISMODULE_POOL_ALLOC_ALIGN;
542 while (bytes < alignment && alignment/2 >= bytes) alignment /= 2;
543 if (b->used % alignment)
544 b->used += alignment - (b->used % alignment);
545 left = (b->used > b->size) ? 0 : b->size - b->used;
546 }
547
548 /* Create a new block if needed. */
549 if (left < bytes) {
550 size_t blocksize = REDISMODULE_POOL_ALLOC_MIN_SIZE;
551 if (blocksize < bytes) blocksize = bytes;
552 b = zmalloc(sizeof(*b) + blocksize);
553 b->size = blocksize;
554 b->used = 0;
555 b->next = ctx->pa_head;
556 ctx->pa_head = b;
557 }
558
559 char *retval = b->memory + b->used;
560 b->used += bytes;
561 return retval;
562}
563
564/* --------------------------------------------------------------------------
565 * Helpers for modules API implementation
566 * -------------------------------------------------------------------------- */
567
568client *moduleAllocTempClient() {
569 client *c = NULL;
570
571 if (moduleTempClientCount > 0) {
572 c = moduleTempClients[--moduleTempClientCount];
573 if (moduleTempClientCount < moduleTempClientMinCount)
574 moduleTempClientMinCount = moduleTempClientCount;
575 } else {
576 c = createClient(NULL);
577 c->flags |= CLIENT_MODULE;
578 c->user = NULL; /* Root user */
579 }
580 return c;
581}
582
583void moduleReleaseTempClient(client *c) {
584 if (moduleTempClientCount == moduleTempClientCap) {
585 moduleTempClientCap = moduleTempClientCap ? moduleTempClientCap*2 : 32;
586 moduleTempClients = zrealloc(moduleTempClients, sizeof(c)*moduleTempClientCap);
587 }
588 clearClientConnectionState(c);
589 listEmpty(c->reply);
590 c->reply_bytes = 0;
591 resetClient(c);
592 c->bufpos = 0;
593 c->flags = CLIENT_MODULE;
594 c->user = NULL; /* Root user */
595 moduleTempClients[moduleTempClientCount++] = c;
596}
597
598/* Create an empty key of the specified type. `key` must point to a key object
599 * opened for writing where the `.value` member is set to NULL because the
600 * key was found to be non existing.
601 *
602 * On success REDISMODULE_OK is returned and the key is populated with
603 * the value of the specified type. The function fails and returns
604 * REDISMODULE_ERR if:
605 *
606 * 1. The key is not open for writing.
607 * 2. The key is not empty.
608 * 3. The specified type is unknown.
609 */
610int moduleCreateEmptyKey(RedisModuleKey *key, int type) {
611 robj *obj;
612
613 /* The key must be open for writing and non existing to proceed. */
614 if (!(key->mode & REDISMODULE_WRITE) || key->value)
615 return REDISMODULE_ERR;
616
617 switch(type) {
618 case REDISMODULE_KEYTYPE_LIST:
619 obj = createQuicklistObject();
620 quicklistSetOptions(obj->ptr, server.list_max_listpack_size,
621 server.list_compress_depth);
622 break;
623 case REDISMODULE_KEYTYPE_ZSET:
624 obj = createZsetListpackObject();
625 break;
626 case REDISMODULE_KEYTYPE_HASH:
627 obj = createHashObject();
628 break;
629 case REDISMODULE_KEYTYPE_STREAM:
630 obj = createStreamObject();
631 break;
632 default: return REDISMODULE_ERR;
633 }
634 dbAdd(key->db,key->key,obj);
635 key->value = obj;
636 moduleInitKeyTypeSpecific(key);
637 return REDISMODULE_OK;
638}
639
640/* Frees key->iter and sets it to NULL. */
641static void moduleFreeKeyIterator(RedisModuleKey *key) {
642 serverAssert(key->iter != NULL);
643 switch (key->value->type) {
644 case OBJ_LIST: listTypeReleaseIterator(key->iter); break;
645 case OBJ_STREAM:
646 streamIteratorStop(key->iter);
647 zfree(key->iter);
648 break;
649 default: serverAssert(0); /* No key->iter for other types. */
650 }
651 key->iter = NULL;
652}
653
654/* This function is called in low-level API implementation functions in order
655 * to check if the value associated with the key remained empty after an
656 * operation that removed elements from an aggregate data type.
657 *
658 * If this happens, the key is deleted from the DB and the key object state
659 * is set to the right one in order to be targeted again by write operations
660 * possibly recreating the key if needed.
661 *
662 * The function returns 1 if the key value object is found empty and is
663 * deleted, otherwise 0 is returned. */
664int moduleDelKeyIfEmpty(RedisModuleKey *key) {
665 if (!(key->mode & REDISMODULE_WRITE) || key->value == NULL) return 0;
666 int isempty;
667 robj *o = key->value;
668
669 switch(o->type) {
670 case OBJ_LIST: isempty = listTypeLength(o) == 0; break;
671 case OBJ_SET: isempty = setTypeSize(o) == 0; break;
672 case OBJ_ZSET: isempty = zsetLength(o) == 0; break;
673 case OBJ_HASH: isempty = hashTypeLength(o) == 0; break;
674 case OBJ_STREAM: isempty = streamLength(o) == 0; break;
675 default: isempty = 0;
676 }
677
678 if (isempty) {
679 if (key->iter) moduleFreeKeyIterator(key);
680 dbDelete(key->db,key->key);
681 key->value = NULL;
682 return 1;
683 } else {
684 return 0;
685 }
686}
687
688/* --------------------------------------------------------------------------
689 * Service API exported to modules
690 *
691 * Note that all the exported APIs are called RM_<funcname> in the core
692 * and RedisModule_<funcname> in the module side (defined as function
693 * pointers in redismodule.h). In this way the dynamic linker does not
694 * mess with our global function pointers, overriding it with the symbols
695 * defined in the main executable having the same names.
696 * -------------------------------------------------------------------------- */
697
698int RM_GetApi(const char *funcname, void **targetPtrPtr) {
699 /* Lookup the requested module API and store the function pointer into the
700 * target pointer. The function returns REDISMODULE_ERR if there is no such
701 * named API, otherwise REDISMODULE_OK.
702 *
703 * This function is not meant to be used by modules developer, it is only
704 * used implicitly by including redismodule.h. */
705 dictEntry *he = dictFind(server.moduleapi, funcname);
706 if (!he) return REDISMODULE_ERR;
707 *targetPtrPtr = dictGetVal(he);
708 return REDISMODULE_OK;
709}
710
711/* Free the context after the user function was called. */
712void moduleFreeContext(RedisModuleCtx *ctx) {
713 if (!(ctx->flags & REDISMODULE_CTX_THREAD_SAFE)) {
714 /* Modules take care of their own propagation, when we are
715 * outside of call() context (timers, events, etc.). */
716 if (--server.module_ctx_nesting == 0) {
717 if (!server.core_propagates)
718 propagatePendingCommands();
719 if (server.busy_module_yield_flags) {
720 blockingOperationEnds();
721 server.busy_module_yield_flags = BUSY_MODULE_YIELD_NONE;
722 if (server.current_client)
723 unprotectClient(server.current_client);
724 unblockPostponedClients();
725 }
726 }
727 }
728 autoMemoryCollect(ctx);
729 poolAllocRelease(ctx);
730 if (ctx->postponed_arrays) {
731 zfree(ctx->postponed_arrays);
732 ctx->postponed_arrays_count = 0;
733 serverLog(LL_WARNING,
734 "API misuse detected in module %s: "
735 "RedisModule_ReplyWith*(REDISMODULE_POSTPONED_LEN) "
736 "not matched by the same number of RedisModule_SetReply*Len() "
737 "calls.",
738 ctx->module->name);
739 }
740 /* If this context has a temp client, we return it back to the pool.
741 * If this context created a new client (e.g detached context), we free it.
742 * If the client is assigned manually, e.g ctx->client = someClientInstance,
743 * none of these flags will be set and we do not attempt to free it. */
744 if (ctx->flags & REDISMODULE_CTX_TEMP_CLIENT)
745 moduleReleaseTempClient(ctx->client);
746 else if (ctx->flags & REDISMODULE_CTX_NEW_CLIENT)
747 freeClient(ctx->client);
748}
749
750/* Create a module ctx and keep track of the nesting level.
751 *
752 * Note: When creating ctx for threads (RM_GetThreadSafeContext and
753 * RM_GetDetachedThreadSafeContext) we do not bump up the nesting level
754 * because we only need to track of nesting level in the main thread
755 * (only the main thread uses propagatePendingCommands) */
756void moduleCreateContext(RedisModuleCtx *out_ctx, RedisModule *module, int ctx_flags) {
757 memset(out_ctx, 0 ,sizeof(RedisModuleCtx));
758 out_ctx->getapifuncptr = (void*)(unsigned long)&RM_GetApi;
759 out_ctx->module = module;
760 out_ctx->flags = ctx_flags;
761 if (ctx_flags & REDISMODULE_CTX_TEMP_CLIENT)
762 out_ctx->client = moduleAllocTempClient();
763 else if (ctx_flags & REDISMODULE_CTX_NEW_CLIENT)
764 out_ctx->client = createClient(NULL);
765
766 /* Calculate the initial yield time for long blocked contexts.
767 * in loading we depend on the server hz, but in other cases we also wait
768 * for busy_reply_threshold.
769 * Note that in theory we could have started processing BUSY_MODULE_YIELD_EVENTS
770 * sooner, and only delay the processing for clients till the busy_reply_threshold,
771 * but this carries some overheads of frequently marking clients with BLOCKED_POSTPONE
772 * and releasing them, i.e. if modules only block for short periods. */
773 if (server.loading)
774 out_ctx->next_yield_time = getMonotonicUs() + 1000000 / server.hz;
775 else
776 out_ctx->next_yield_time = getMonotonicUs() + server.busy_reply_threshold * 1000;
777
778 if (!(ctx_flags & REDISMODULE_CTX_THREAD_SAFE)) {
779 server.module_ctx_nesting++;
780 }
781}
782
783/* This Redis command binds the normal Redis command invocation with commands
784 * exported by modules. */
785void RedisModuleCommandDispatcher(client *c) {
786 RedisModuleCommand *cp = c->cmd->module_cmd;
787 RedisModuleCtx ctx;
788 moduleCreateContext(&ctx, cp->module, REDISMODULE_CTX_NONE);
789
790 ctx.client = c;
791 cp->func(&ctx,(void**)c->argv,c->argc);
792 moduleFreeContext(&ctx);
793
794 /* In some cases processMultibulkBuffer uses sdsMakeRoomFor to
795 * expand the query buffer, and in order to avoid a big object copy
796 * the query buffer SDS may be used directly as the SDS string backing
797 * the client argument vectors: sometimes this will result in the SDS
798 * string having unused space at the end. Later if a module takes ownership
799 * of the RedisString, such space will be wasted forever. Inside the
800 * Redis core this is not a problem because tryObjectEncoding() is called
801 * before storing strings in the key space. Here we need to do it
802 * for the module. */
803 for (int i = 0; i < c->argc; i++) {
804 /* Only do the work if the module took ownership of the object:
805 * in that case the refcount is no longer 1. */
806 if (c->argv[i]->refcount > 1)
807 trimStringObjectIfNeeded(c->argv[i]);
808 }
809}
810
811/* This function returns the list of keys, with the same interface as the
812 * 'getkeys' function of the native commands, for module commands that exported
813 * the "getkeys-api" flag during the registration. This is done when the
814 * list of keys are not at fixed positions, so that first/last/step cannot
815 * be used.
816 *
817 * In order to accomplish its work, the module command is called, flagging
818 * the context in a way that the command can recognize this is a special
819 * "get keys" call by calling RedisModule_IsKeysPositionRequest(ctx). */
820int moduleGetCommandKeysViaAPI(struct redisCommand *cmd, robj **argv, int argc, getKeysResult *result) {
821 RedisModuleCommand *cp = cmd->module_cmd;
822 RedisModuleCtx ctx;
823 moduleCreateContext(&ctx, cp->module, REDISMODULE_CTX_KEYS_POS_REQUEST);
824
825 /* Initialize getKeysResult */
826 getKeysPrepareResult(result, MAX_KEYS_BUFFER);
827 ctx.keys_result = result;
828
829 cp->func(&ctx,(void**)argv,argc);
830 /* We currently always use the array allocated by RM_KeyAtPos() and don't try
831 * to optimize for the pre-allocated buffer.
832 */
833 moduleFreeContext(&ctx);
834 return result->numkeys;
835}
836
837/* This function returns the list of channels, with the same interface as
838 * moduleGetCommandKeysViaAPI, for modules that declare "getchannels-api"
839 * during registration. Unlike keys, this is the only way to declare channels. */
840int moduleGetCommandChannelsViaAPI(struct redisCommand *cmd, robj **argv, int argc, getKeysResult *result) {
841 RedisModuleCommand *cp = cmd->module_cmd;
842 RedisModuleCtx ctx;
843 moduleCreateContext(&ctx, cp->module, REDISMODULE_CTX_CHANNELS_POS_REQUEST);
844
845 /* Initialize getKeysResult */
846 getKeysPrepareResult(result, MAX_KEYS_BUFFER);
847 ctx.keys_result = result;
848
849 cp->func(&ctx,(void**)argv,argc);
850 /* We currently always use the array allocated by RM_RM_ChannelAtPosWithFlags() and don't try
851 * to optimize for the pre-allocated buffer. */
852 moduleFreeContext(&ctx);
853 return result->numkeys;
854}
855
856/* --------------------------------------------------------------------------
857 * ## Commands API
858 *
859 * These functions are used to implement custom Redis commands.
860 *
861 * For examples, see https://redis.io/topics/modules-intro.
862 * -------------------------------------------------------------------------- */
863
864/* Return non-zero if a module command, that was declared with the
865 * flag "getkeys-api", is called in a special way to get the keys positions
866 * and not to get executed. Otherwise zero is returned. */
867int RM_IsKeysPositionRequest(RedisModuleCtx *ctx) {
868 return (ctx->flags & REDISMODULE_CTX_KEYS_POS_REQUEST) != 0;
869}
870
871/* When a module command is called in order to obtain the position of
872 * keys, since it was flagged as "getkeys-api" during the registration,
873 * the command implementation checks for this special call using the
874 * RedisModule_IsKeysPositionRequest() API and uses this function in
875 * order to report keys.
876 *
877 * The supported flags are the ones used by RM_SetCommandInfo, see REDISMODULE_CMD_KEY_*.
878 *
879 *
880 * The following is an example of how it could be used:
881 *
882 * if (RedisModule_IsKeysPositionRequest(ctx)) {
883 * RedisModule_KeyAtPosWithFlags(ctx, 2, REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_ACCESS);
884 * RedisModule_KeyAtPosWithFlags(ctx, 1, REDISMODULE_CMD_KEY_RW | REDISMODULE_CMD_KEY_UPDATE | REDISMODULE_CMD_KEY_ACCESS);
885 * }
886 *
887 * Note: in the example above the get keys API could have been handled by key-specs (preferred).
888 * Implementing the getkeys-api is required only when is it not possible to declare key-specs that cover all keys.
889 *
890 */
891void RM_KeyAtPosWithFlags(RedisModuleCtx *ctx, int pos, int flags) {
892 if (!(ctx->flags & REDISMODULE_CTX_KEYS_POS_REQUEST) || !ctx->keys_result) return;
893 if (pos <= 0) return;
894
895 getKeysResult *res = ctx->keys_result;
896
897 /* Check overflow */
898 if (res->numkeys == res->size) {
899 int newsize = res->size + (res->size > 8192 ? 8192 : res->size);
900 getKeysPrepareResult(res, newsize);
901 }
902
903 res->keys[res->numkeys].pos = pos;
904 res->keys[res->numkeys].flags = moduleConvertKeySpecsFlags(flags, 1);
905 res->numkeys++;
906}
907
908/* This API existed before RM_KeyAtPosWithFlags was added, now deprecated and
909 * can be used for compatibility with older versions, before key-specs and flags
910 * were introduced. */
911void RM_KeyAtPos(RedisModuleCtx *ctx, int pos) {
912 /* Default flags require full access */
913 int flags = moduleConvertKeySpecsFlags(CMD_KEY_FULL_ACCESS, 0);
914 RM_KeyAtPosWithFlags(ctx, pos, flags);
915}
916
917/* Return non-zero if a module command, that was declared with the
918 * flag "getchannels-api", is called in a special way to get the channel positions
919 * and not to get executed. Otherwise zero is returned. */
920int RM_IsChannelsPositionRequest(RedisModuleCtx *ctx) {
921 return (ctx->flags & REDISMODULE_CTX_CHANNELS_POS_REQUEST) != 0;
922}
923
924/* When a module command is called in order to obtain the position of
925 * channels, since it was flagged as "getchannels-api" during the
926 * registration, the command implementation checks for this special call
927 * using the RedisModule_IsChannelsPositionRequest() API and uses this
928 * function in order to report the channels.
929 *
930 * The supported flags are:
931 * * REDISMODULE_CMD_CHANNEL_SUBSCRIBE: This command will subscribe to the channel.
932 * * REDISMODULE_CMD_CHANNEL_UNSUBSCRIBE: This command will unsubscribe from this channel.
933 * * REDISMODULE_CMD_CHANNEL_PUBLISH: This command will publish to this channel.
934 * * REDISMODULE_CMD_CHANNEL_PATTERN: Instead of acting on a specific channel, will act on any
935 * channel specified by the pattern. This is the same access
936 * used by the PSUBSCRIBE and PUNSUBSCRIBE commands available
937 * in Redis. Not intended to be used with PUBLISH permissions.
938 *
939 * The following is an example of how it could be used:
940 *
941 * if (RedisModule_IsChannelsPositionRequest(ctx)) {
942 * RedisModule_ChannelAtPosWithFlags(ctx, 1, REDISMODULE_CMD_CHANNEL_SUBSCRIBE | REDISMODULE_CMD_CHANNEL_PATTERN);
943 * RedisModule_ChannelAtPosWithFlags(ctx, 1, REDISMODULE_CMD_CHANNEL_PUBLISH);
944 * }
945 *
946 * Note: One usage of declaring channels is for evaluating ACL permissions. In this context,
947 * unsubscribing is always allowed, so commands will only be checked against subscribe and
948 * publish permissions. This is preferred over using RM_ACLCheckChannelPermissions, since
949 * it allows the ACLs to be checked before the command is executed. */
950void RM_ChannelAtPosWithFlags(RedisModuleCtx *ctx, int pos, int flags) {
951 if (!(ctx->flags & REDISMODULE_CTX_CHANNELS_POS_REQUEST) || !ctx->keys_result) return;
952 if (pos <= 0) return;
953
954 getKeysResult *res = ctx->keys_result;
955
956 /* Check overflow */
957 if (res->numkeys == res->size) {
958 int newsize = res->size + (res->size > 8192 ? 8192 : res->size);
959 getKeysPrepareResult(res, newsize);
960 }
961
962 int new_flags = 0;
963 if (flags & REDISMODULE_CMD_CHANNEL_SUBSCRIBE) new_flags |= CMD_CHANNEL_SUBSCRIBE;
964 if (flags & REDISMODULE_CMD_CHANNEL_UNSUBSCRIBE) new_flags |= CMD_CHANNEL_UNSUBSCRIBE;
965 if (flags & REDISMODULE_CMD_CHANNEL_PUBLISH) new_flags |= CMD_CHANNEL_PUBLISH;
966 if (flags & REDISMODULE_CMD_CHANNEL_PATTERN) new_flags |= CMD_CHANNEL_PATTERN;
967
968 res->keys[res->numkeys].pos = pos;
969 res->keys[res->numkeys].flags = new_flags;
970 res->numkeys++;
971}
972
973/* Helper for RM_CreateCommand(). Turns a string representing command
974 * flags into the command flags used by the Redis core.
975 *
976 * It returns the set of flags, or -1 if unknown flags are found. */
977int64_t commandFlagsFromString(char *s) {
978 int count, j;
979 int64_t flags = 0;
980 sds *tokens = sdssplitlen(s,strlen(s)," ",1,&count);
981 for (j = 0; j < count; j++) {
982 char *t = tokens[j];
983 if (!strcasecmp(t,"write")) flags |= CMD_WRITE;
984 else if (!strcasecmp(t,"readonly")) flags |= CMD_READONLY;
985 else if (!strcasecmp(t,"admin")) flags |= CMD_ADMIN;
986 else if (!strcasecmp(t,"deny-oom")) flags |= CMD_DENYOOM;
987 else if (!strcasecmp(t,"deny-script")) flags |= CMD_NOSCRIPT;
988 else if (!strcasecmp(t,"allow-loading")) flags |= CMD_LOADING;
989 else if (!strcasecmp(t,"pubsub")) flags |= CMD_PUBSUB;
990 else if (!strcasecmp(t,"random")) { /* Deprecated. Silently ignore. */ }
991 else if (!strcasecmp(t,"blocking")) flags |= CMD_BLOCKING;
992 else if (!strcasecmp(t,"allow-stale")) flags |= CMD_STALE;
993 else if (!strcasecmp(t,"no-monitor")) flags |= CMD_SKIP_MONITOR;
994 else if (!strcasecmp(t,"no-slowlog")) flags |= CMD_SKIP_SLOWLOG;
995 else if (!strcasecmp(t,"fast")) flags |= CMD_FAST;
996 else if (!strcasecmp(t,"no-auth")) flags |= CMD_NO_AUTH;
997 else if (!strcasecmp(t,"may-replicate")) flags |= CMD_MAY_REPLICATE;
998 else if (!strcasecmp(t,"getkeys-api")) flags |= CMD_MODULE_GETKEYS;
999 else if (!strcasecmp(t,"getchannels-api")) flags |= CMD_MODULE_GETCHANNELS;
1000 else if (!strcasecmp(t,"no-cluster")) flags |= CMD_MODULE_NO_CLUSTER;
1001 else if (!strcasecmp(t,"no-mandatory-keys")) flags |= CMD_NO_MANDATORY_KEYS;
1002 else if (!strcasecmp(t,"allow-busy")) flags |= CMD_ALLOW_BUSY;
1003 else break;
1004 }
1005 sdsfreesplitres(tokens,count);
1006 if (j != count) return -1; /* Some token not processed correctly. */
1007 return flags;
1008}
1009
1010RedisModuleCommand *moduleCreateCommandProxy(struct RedisModule *module, sds declared_name, sds fullname, RedisModuleCmdFunc cmdfunc, int64_t flags, int firstkey, int lastkey, int keystep);
1011
1012/* Register a new command in the Redis server, that will be handled by
1013 * calling the function pointer 'cmdfunc' using the RedisModule calling
1014 * convention. The function returns REDISMODULE_ERR if the specified command
1015 * name is already busy or a set of invalid flags were passed, otherwise
1016 * REDISMODULE_OK is returned and the new command is registered.
1017 *
1018 * This function must be called during the initialization of the module
1019 * inside the RedisModule_OnLoad() function. Calling this function outside
1020 * of the initialization function is not defined.
1021 *
1022 * The command function type is the following:
1023 *
1024 * int MyCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
1025 *
1026 * And is supposed to always return REDISMODULE_OK.
1027 *
1028 * The set of flags 'strflags' specify the behavior of the command, and should
1029 * be passed as a C string composed of space separated words, like for
1030 * example "write deny-oom". The set of flags are:
1031 *
1032 * * **"write"**: The command may modify the data set (it may also read
1033 * from it).
1034 * * **"readonly"**: The command returns data from keys but never writes.
1035 * * **"admin"**: The command is an administrative command (may change
1036 * replication or perform similar tasks).
1037 * * **"deny-oom"**: The command may use additional memory and should be
1038 * denied during out of memory conditions.
1039 * * **"deny-script"**: Don't allow this command in Lua scripts.
1040 * * **"allow-loading"**: Allow this command while the server is loading data.
1041 * Only commands not interacting with the data set
1042 * should be allowed to run in this mode. If not sure
1043 * don't use this flag.
1044 * * **"pubsub"**: The command publishes things on Pub/Sub channels.
1045 * * **"random"**: The command may have different outputs even starting
1046 * from the same input arguments and key values.
1047 * Starting from Redis 7.0 this flag has been deprecated.
1048 * Declaring a command as "random" can be done using
1049 * command tips, see https://redis.io/topics/command-tips.
1050 * * **"allow-stale"**: The command is allowed to run on slaves that don't
1051 * serve stale data. Don't use if you don't know what
1052 * this means.
1053 * * **"no-monitor"**: Don't propagate the command on monitor. Use this if
1054 * the command has sensitive data among the arguments.
1055 * * **"no-slowlog"**: Don't log this command in the slowlog. Use this if
1056 * the command has sensitive data among the arguments.
1057 * * **"fast"**: The command time complexity is not greater
1058 * than O(log(N)) where N is the size of the collection or
1059 * anything else representing the normal scalability
1060 * issue with the command.
1061 * * **"getkeys-api"**: The command implements the interface to return
1062 * the arguments that are keys. Used when start/stop/step
1063 * is not enough because of the command syntax.
1064 * * **"no-cluster"**: The command should not register in Redis Cluster
1065 * since is not designed to work with it because, for
1066 * example, is unable to report the position of the
1067 * keys, programmatically creates key names, or any
1068 * other reason.
1069 * * **"no-auth"**: This command can be run by an un-authenticated client.
1070 * Normally this is used by a command that is used
1071 * to authenticate a client.
1072 * * **"may-replicate"**: This command may generate replication traffic, even
1073 * though it's not a write command.
1074 * * **"no-mandatory-keys"**: All the keys this command may take are optional
1075 * * **"blocking"**: The command has the potential to block the client.
1076 * * **"allow-busy"**: Permit the command while the server is blocked either by
1077 * a script or by a slow module command, see
1078 * RM_Yield.
1079 * * **"getchannels-api"**: The command implements the interface to return
1080 * the arguments that are channels.
1081 *
1082 * The last three parameters specify which arguments of the new command are
1083 * Redis keys. See https://redis.io/commands/command for more information.
1084 *
1085 * * `firstkey`: One-based index of the first argument that's a key.
1086 * Position 0 is always the command name itself.
1087 * 0 for commands with no keys.
1088 * * `lastkey`: One-based index of the last argument that's a key.
1089 * Negative numbers refer to counting backwards from the last
1090 * argument (-1 means the last argument provided)
1091 * 0 for commands with no keys.
1092 * * `keystep`: Step between first and last key indexes.
1093 * 0 for commands with no keys.
1094 *
1095 * This information is used by ACL, Cluster and the `COMMAND` command.
1096 *
1097 * NOTE: The scheme described above serves a limited purpose and can
1098 * only be used to find keys that exist at constant indices.
1099 * For non-trivial key arguments, you may pass 0,0,0 and use
1100 * RedisModule_SetCommandInfo to set key specs using a more advanced scheme. */
1101int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) {
1102 int64_t flags = strflags ? commandFlagsFromString((char*)strflags) : 0;
1103 if (flags == -1) return REDISMODULE_ERR;
1104 if ((flags & CMD_MODULE_NO_CLUSTER) && server.cluster_enabled)
1105 return REDISMODULE_ERR;
1106
1107 /* Check if the command name is busy. */
1108 if (lookupCommandByCString(name) != NULL)
1109 return REDISMODULE_ERR;
1110
1111 sds declared_name = sdsnew(name);
1112 RedisModuleCommand *cp = moduleCreateCommandProxy(ctx->module, declared_name, sdsdup(declared_name), cmdfunc, flags, firstkey, lastkey, keystep);
1113 cp->rediscmd->arity = cmdfunc ? -1 : -2; /* Default value, can be changed later via dedicated API */
1114
1115 serverAssert(dictAdd(server.commands, sdsdup(declared_name), cp->rediscmd) == DICT_OK);
1116 serverAssert(dictAdd(server.orig_commands, sdsdup(declared_name), cp->rediscmd) == DICT_OK);
1117 cp->rediscmd->id = ACLGetCommandID(declared_name); /* ID used for ACL. */
1118 return REDISMODULE_OK;
1119}
1120
1121/* A proxy that help create a module command / subcommand.
1122 *
1123 * 'declared_name': it contains the sub_name, which is just the fullname for non-subcommands.
1124 * 'fullname': sds string representing the command fullname.
1125 *
1126 * Function will take the ownership of both 'declared_name' and 'fullname' SDS.
1127 */
1128RedisModuleCommand *moduleCreateCommandProxy(struct RedisModule *module, sds declared_name, sds fullname, RedisModuleCmdFunc cmdfunc, int64_t flags, int firstkey, int lastkey, int keystep) {
1129 struct redisCommand *rediscmd;
1130 RedisModuleCommand *cp;
1131
1132 /* Create a command "proxy", which is a structure that is referenced
1133 * in the command table, so that the generic command that works as
1134 * binding between modules and Redis, can know what function to call
1135 * and what the module is. */
1136 cp = zcalloc(sizeof(*cp));
1137 cp->module = module;
1138 cp->func = cmdfunc;
1139 cp->rediscmd = zcalloc(sizeof(*rediscmd));
1140 cp->rediscmd->declared_name = declared_name; /* SDS for module commands */
1141 cp->rediscmd->fullname = fullname;
1142 cp->rediscmd->group = COMMAND_GROUP_MODULE;
1143 cp->rediscmd->proc = RedisModuleCommandDispatcher;
1144 cp->rediscmd->flags = flags | CMD_MODULE;
1145 cp->rediscmd->module_cmd = cp;
1146 cp->rediscmd->key_specs_max = STATIC_KEY_SPECS_NUM;
1147 cp->rediscmd->key_specs = cp->rediscmd->key_specs_static;
1148 if (firstkey != 0) {
1149 cp->rediscmd->key_specs_num = 1;
1150 cp->rediscmd->key_specs[0].flags = CMD_KEY_FULL_ACCESS | CMD_KEY_VARIABLE_FLAGS;
1151 cp->rediscmd->key_specs[0].begin_search_type = KSPEC_BS_INDEX;
1152 cp->rediscmd->key_specs[0].bs.index.pos = firstkey;
1153 cp->rediscmd->key_specs[0].find_keys_type = KSPEC_FK_RANGE;
1154 cp->rediscmd->key_specs[0].fk.range.lastkey = lastkey < 0 ? lastkey : (lastkey-firstkey);
1155 cp->rediscmd->key_specs[0].fk.range.keystep = keystep;
1156 cp->rediscmd->key_specs[0].fk.range.limit = 0;
1157 } else {
1158 cp->rediscmd->key_specs_num = 0;
1159 }
1160 populateCommandLegacyRangeSpec(cp->rediscmd);
1161 cp->rediscmd->microseconds = 0;
1162 cp->rediscmd->calls = 0;
1163 cp->rediscmd->rejected_calls = 0;
1164 cp->rediscmd->failed_calls = 0;
1165 return cp;
1166}
1167
1168/* Get an opaque structure, representing a module command, by command name.
1169 * This structure is used in some of the command-related APIs.
1170 *
1171 * NULL is returned in case of the following errors:
1172 *
1173 * * Command not found
1174 * * The command is not a module command
1175 * * The command doesn't belong to the calling module
1176 */
1177RedisModuleCommand *RM_GetCommand(RedisModuleCtx *ctx, const char *name) {
1178 struct redisCommand *cmd = lookupCommandByCString(name);
1179
1180 if (!cmd || !(cmd->flags & CMD_MODULE))
1181 return NULL;
1182
1183 RedisModuleCommand *cp = cmd->module_cmd;
1184 if (cp->module != ctx->module)
1185 return NULL;
1186
1187 return cp;
1188}
1189
1190/* Very similar to RedisModule_CreateCommand except that it is used to create
1191 * a subcommand, associated with another, container, command.
1192 *
1193 * Example: If a module has a configuration command, MODULE.CONFIG, then
1194 * GET and SET should be individual subcommands, while MODULE.CONFIG is
1195 * a command, but should not be registered with a valid `funcptr`:
1196 *
1197 * if (RedisModule_CreateCommand(ctx,"module.config",NULL,"",0,0,0) == REDISMODULE_ERR)
1198 * return REDISMODULE_ERR;
1199 *
1200 * RedisModuleCommand *parent = RedisModule_GetCommand(ctx,,"module.config");
1201 *
1202 * if (RedisModule_CreateSubcommand(parent,"set",cmd_config_set,"",0,0,0) == REDISMODULE_ERR)
1203 * return REDISMODULE_ERR;
1204 *
1205 * if (RedisModule_CreateSubcommand(parent,"get",cmd_config_get,"",0,0,0) == REDISMODULE_ERR)
1206 * return REDISMODULE_ERR;
1207 *
1208 * Returns REDISMODULE_OK on success and REDISMODULE_ERR in case of the following errors:
1209 *
1210 * * Error while parsing `strflags`
1211 * * Command is marked as `no-cluster` but cluster mode is enabled
1212 * * `parent` is already a subcommand (we do not allow more than one level of command nesting)
1213 * * `parent` is a command with an implementation (RedisModuleCmdFunc) (A parent command should be a pure container of subcommands)
1214 * * `parent` already has a subcommand called `name`
1215 */
1216int RM_CreateSubcommand(RedisModuleCommand *parent, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep) {
1217 int64_t flags = strflags ? commandFlagsFromString((char*)strflags) : 0;
1218 if (flags == -1) return REDISMODULE_ERR;
1219 if ((flags & CMD_MODULE_NO_CLUSTER) && server.cluster_enabled)
1220 return REDISMODULE_ERR;
1221
1222 struct redisCommand *parent_cmd = parent->rediscmd;
1223
1224 if (parent_cmd->parent)
1225 return REDISMODULE_ERR; /* We don't allow more than one level of subcommands */
1226
1227 RedisModuleCommand *parent_cp = parent_cmd->module_cmd;
1228 if (parent_cp->func)
1229 return REDISMODULE_ERR; /* A parent command should be a pure container of subcommands */
1230
1231 /* Check if the command name is busy within the parent command. */
1232 sds declared_name = sdsnew(name);
1233 if (parent_cmd->subcommands_dict && lookupSubcommand(parent_cmd, declared_name) != NULL) {
1234 sdsfree(declared_name);
1235 return REDISMODULE_ERR;
1236 }
1237
1238 sds fullname = catSubCommandFullname(parent_cmd->fullname, name);
1239 RedisModuleCommand *cp = moduleCreateCommandProxy(parent->module, declared_name, fullname, cmdfunc, flags, firstkey, lastkey, keystep);
1240 cp->rediscmd->arity = -2;
1241
1242 commandAddSubcommand(parent_cmd, cp->rediscmd, name);
1243 return REDISMODULE_OK;
1244}
1245
1246/* Accessors of array elements of structs where the element size is stored
1247 * separately in the version struct. */
1248static RedisModuleCommandHistoryEntry *
1249moduleCmdHistoryEntryAt(const RedisModuleCommandInfoVersion *version,
1250 RedisModuleCommandHistoryEntry *entries, int index) {
1251 off_t offset = index * version->sizeof_historyentry;
1252 return (RedisModuleCommandHistoryEntry *)((char *)(entries) + offset);
1253}
1254static RedisModuleCommandKeySpec *
1255moduleCmdKeySpecAt(const RedisModuleCommandInfoVersion *version,
1256 RedisModuleCommandKeySpec *keyspecs, int index) {
1257 off_t offset = index * version->sizeof_keyspec;
1258 return (RedisModuleCommandKeySpec *)((char *)(keyspecs) + offset);
1259}
1260static RedisModuleCommandArg *
1261moduleCmdArgAt(const RedisModuleCommandInfoVersion *version,
1262 const RedisModuleCommandArg *args, int index) {
1263 off_t offset = index * version->sizeof_arg;
1264 return (RedisModuleCommandArg *)((char *)(args) + offset);
1265}
1266
1267/* Set additional command information.
1268 *
1269 * Affects the output of `COMMAND`, `COMMAND INFO` and `COMMAND DOCS`, Cluster,
1270 * ACL and is used to filter commands with the wrong number of arguments before
1271 * the call reaches the module code.
1272 *
1273 * This function can be called after creating a command using RM_CreateCommand
1274 * and fetching the command pointer using RM_GetCommand. The information can
1275 * only be set once for each command and has the following structure:
1276 *
1277 * typedef struct RedisModuleCommandInfo {
1278 * const RedisModuleCommandInfoVersion *version;
1279 * const char *summary;
1280 * const char *complexity;
1281 * const char *since;
1282 * RedisModuleCommandHistoryEntry *history;
1283 * const char *tips;
1284 * int arity;
1285 * RedisModuleCommandKeySpec *key_specs;
1286 * RedisModuleCommandArg *args;
1287 * } RedisModuleCommandInfo;
1288 *
1289 * All fields except `version` are optional. Explanation of the fields:
1290 *
1291 * - `version`: This field enables compatibility with different Redis versions.
1292 * Always set this field to REDISMODULE_COMMAND_INFO_VERSION.
1293 *
1294 * - `summary`: A short description of the command (optional).
1295 *
1296 * - `complexity`: Complexity description (optional).
1297 *
1298 * - `since`: The version where the command was introduced (optional).
1299 * Note: The version specified should be the module's, not Redis version.
1300 *
1301 * - `history`: An array of RedisModuleCommandHistoryEntry (optional), which is
1302 * a struct with the following fields:
1303 *
1304 * const char *since;
1305 * const char *changes;
1306 *
1307 * `since` is a version string and `changes` is a string describing the
1308 * changes. The array is terminated by a zeroed entry, i.e. an entry with
1309 * both strings set to NULL.
1310 *
1311 * - `tips`: A string of space-separated tips regarding this command, meant for
1312 * clients and proxies. See https://redis.io/topics/command-tips.
1313 *
1314 * - `arity`: Number of arguments, including the command name itself. A positive
1315 * number specifies an exact number of arguments and a negative number
1316 * specifies a minimum number of arguments, so use -N to say >= N. Redis
1317 * validates a call before passing it to a module, so this can replace an
1318 * arity check inside the module command implementation. A value of 0 (or an
1319 * omitted arity field) is equivalent to -2 if the command has sub commands
1320 * and -1 otherwise.
1321 *
1322 * - `key_specs`: An array of RedisModuleCommandKeySpec, terminated by an
1323 * element memset to zero. This is a scheme that tries to describe the
1324 * positions of key arguments better than the old RM_CreateCommand arguments
1325 * `firstkey`, `lastkey`, `keystep` and is needed if those three are not
1326 * enough to describe the key positions. There are two steps to retrieve key
1327 * positions: *begin search* (BS) in which index should find the first key and
1328 * *find keys* (FK) which, relative to the output of BS, describes how can we
1329 * will which arguments are keys. Additionally, there are key specific flags.
1330 *
1331 * Key-specs cause the triplet (firstkey, lastkey, keystep) given in
1332 * RM_CreateCommand to be recomputed, but it is still useful to provide
1333 * these three parameters in RM_CreateCommand, to better support old Redis
1334 * versions where RM_SetCommandInfo is not available.
1335 *
1336 * Note that key-specs don't fully replace the "getkeys-api" (see
1337 * RM_CreateCommand, RM_IsKeysPositionRequest and RM_KeyAtPosWithFlags) so
1338 * it may be a good idea to supply both key-specs and implement the
1339 * getkeys-api.
1340 *
1341 * A key-spec has the following structure:
1342 *
1343 * typedef struct RedisModuleCommandKeySpec {
1344 * const char *notes;
1345 * uint64_t flags;
1346 * RedisModuleKeySpecBeginSearchType begin_search_type;
1347 * union {
1348 * struct {
1349 * int pos;
1350 * } index;
1351 * struct {
1352 * const char *keyword;
1353 * int startfrom;
1354 * } keyword;
1355 * } bs;
1356 * RedisModuleKeySpecFindKeysType find_keys_type;
1357 * union {
1358 * struct {
1359 * int lastkey;
1360 * int keystep;
1361 * int limit;
1362 * } range;
1363 * struct {
1364 * int keynumidx;
1365 * int firstkey;
1366 * int keystep;
1367 * } keynum;
1368 * } fk;
1369 * } RedisModuleCommandKeySpec;
1370 *
1371 * Explanation of the fields of RedisModuleCommandKeySpec:
1372 *
1373 * * `notes`: Optional notes or clarifications about this key spec.
1374 *
1375 * * `flags`: A bitwise or of key-spec flags described below.
1376 *
1377 * * `begin_search_type`: This describes how the first key is discovered.
1378 * There are two ways to determine the first key:
1379 *
1380 * * `REDISMODULE_KSPEC_BS_UNKNOWN`: There is no way to tell where the
1381 * key args start.
1382 * * `REDISMODULE_KSPEC_BS_INDEX`: Key args start at a constant index.
1383 * * `REDISMODULE_KSPEC_BS_KEYWORD`: Key args start just after a
1384 * specific keyword.
1385 *
1386 * * `bs`: This is a union in which the `index` or `keyword` branch is used
1387 * depending on the value of the `begin_search_type` field.
1388 *
1389 * * `bs.index.pos`: The index from which we start the search for keys.
1390 * (`REDISMODULE_KSPEC_BS_INDEX` only.)
1391 *
1392 * * `bs.keyword.keyword`: The keyword (string) that indicates the
1393 * beginning of key arguments. (`REDISMODULE_KSPEC_BS_KEYWORD` only.)
1394 *
1395 * * `bs.keyword.startfrom`: An index in argv from which to start
1396 * searching. Can be negative, which means start search from the end,
1397 * in reverse. Example: -2 means to start in reverse from the
1398 * penultimate argument. (`REDISMODULE_KSPEC_BS_KEYWORD` only.)
1399 *
1400 * * `find_keys_type`: After the "begin search", this describes which
1401 * arguments are keys. The strategies are:
1402 *
1403 * * `REDISMODULE_KSPEC_BS_UNKNOWN`: There is no way to tell where the
1404 * key args are located.
1405 * * `REDISMODULE_KSPEC_FK_RANGE`: Keys end at a specific index (or
1406 * relative to the last argument).
1407 * * `REDISMODULE_KSPEC_FK_KEYNUM`: There's an argument that contains
1408 * the number of key args somewhere before the keys themselves.
1409 *
1410 * `find_keys_type` and `fk` can be omitted if this keyspec describes
1411 * exactly one key.
1412 *
1413 * * `fk`: This is a union in which the `range` or `keynum` branch is used
1414 * depending on the value of the `find_keys_type` field.
1415 *
1416 * * `fk.range` (for `REDISMODULE_KSPEC_FK_RANGE`): A struct with the
1417 * following fields:
1418 *
1419 * * `lastkey`: Index of the last key relative to the result of the
1420 * begin search step. Can be negative, in which case it's not
1421 * relative. -1 indicates the last argument, -2 one before the
1422 * last and so on.
1423 *
1424 * * `keystep`: How many arguments should we skip after finding a
1425 * key, in order to find the next one?
1426 *
1427 * * `limit`: If `lastkey` is -1, we use `limit` to stop the search
1428 * by a factor. 0 and 1 mean no limit. 2 means 1/2 of the
1429 * remaining args, 3 means 1/3, and so on.
1430 *
1431 * * `fk.keynum` (for `REDISMODULE_KSPEC_FK_KEYNUM`): A struct with the
1432 * following fields:
1433 *
1434 * * `keynumidx`: Index of the argument containing the number of
1435 * keys to come, relative to the result of the begin search step.
1436 *
1437 * * `firstkey`: Index of the fist key relative to the result of the
1438 * begin search step. (Usually it's just after `keynumidx`, in
1439 * which case it should be set to `keynumidx + 1`.)
1440 *
1441 * * `keystep`: How many arguments should we skip after finding a
1442 * key, in order to find the next one?
1443 *
1444 * Key-spec flags:
1445 *
1446 * The first four refer to what the command actually does with the *value or
1447 * metadata of the key*, and not necessarily the user data or how it affects
1448 * it. Each key-spec may must have exactly one of these. Any operation
1449 * that's not distinctly deletion, overwrite or read-only would be marked as
1450 * RW.
1451 *
1452 * * `REDISMODULE_CMD_KEY_RO`: Read-Only. Reads the value of the key, but
1453 * doesn't necessarily return it.
1454 *
1455 * * `REDISMODULE_CMD_KEY_RW`: Read-Write. Modifies the data stored in the
1456 * value of the key or its metadata.
1457 *
1458 * * `REDISMODULE_CMD_KEY_OW`: Overwrite. Overwrites the data stored in the
1459 * value of the key.
1460 *
1461 * * `REDISMODULE_CMD_KEY_RM`: Deletes the key.
1462 *
1463 * The next four refer to *user data inside the value of the key*, not the
1464 * metadata like LRU, type, cardinality. It refers to the logical operation
1465 * on the user's data (actual input strings or TTL), being
1466 * used/returned/copied/changed. It doesn't refer to modification or
1467 * returning of metadata (like type, count, presence of data). ACCESS can be
1468 * combined with one of the write operations INSERT, DELETE or UPDATE. Any
1469 * write that's not an INSERT or a DELETE would be UPDATE.
1470 *
1471 * * `REDISMODULE_CMD_KEY_ACCESS`: Returns, copies or uses the user data
1472 * from the value of the key.
1473 *
1474 * * `REDISMODULE_CMD_KEY_UPDATE`: Updates data to the value, new value may
1475 * depend on the old value.
1476 *
1477 * * `REDISMODULE_CMD_KEY_INSERT`: Adds data to the value with no chance of
1478 * modification or deletion of existing data.
1479 *
1480 * * `REDISMODULE_CMD_KEY_DELETE`: Explicitly deletes some content from the
1481 * value of the key.
1482 *
1483 * Other flags:
1484 *
1485 * * `REDISMODULE_CMD_KEY_NOT_KEY`: The key is not actually a key, but
1486 * should be routed in cluster mode as if it was a key.
1487 *
1488 * * `REDISMODULE_CMD_KEY_INCOMPLETE`: The keyspec might not point out all
1489 * the keys it should cover.
1490 *
1491 * * `REDISMODULE_CMD_KEY_VARIABLE_FLAGS`: Some keys might have different
1492 * flags depending on arguments.
1493 *
1494 * - `args`: An array of RedisModuleCommandArg, terminated by an element memset
1495 * to zero. RedisModuleCommandArg is a structure with at the fields described
1496 * below.
1497 *
1498 * typedef struct RedisModuleCommandArg {
1499 * const char *name;
1500 * RedisModuleCommandArgType type;
1501 * int key_spec_index;
1502 * const char *token;
1503 * const char *summary;
1504 * const char *since;
1505 * int flags;
1506 * struct RedisModuleCommandArg *subargs;
1507 * } RedisModuleCommandArg;
1508 *
1509 * Explanation of the fields:
1510 *
1511 * * `name`: Name of the argument.
1512 *
1513 * * `type`: The type of the argument. See below for details. The types
1514 * `REDISMODULE_ARG_TYPE_ONEOF` and `REDISMODULE_ARG_TYPE_BLOCK` require
1515 * an argument to have sub-arguments, i.e. `subargs`.
1516 *
1517 * * `key_spec_index`: If the `type` is `REDISMODULE_ARG_TYPE_KEY` you must
1518 * provide the index of the key-spec associated with this argument. See
1519 * `key_specs` above. If the argument is not a key, you may specify -1.
1520 *
1521 * * `token`: The token preceding the argument (optional). Example: the
1522 * argument `seconds` in `SET` has a token `EX`. If the argument consists
1523 * of only a token (for example `NX` in `SET`) the type should be
1524 * `REDISMODULE_ARG_TYPE_PURE_TOKEN` and `value` should be NULL.
1525 *
1526 * * `summary`: A short description of the argument (optional).
1527 *
1528 * * `since`: The first version which included this argument (optional).
1529 *
1530 * * `flags`: A bitwise or of the macros `REDISMODULE_CMD_ARG_*`. See below.
1531 *
1532 * * `value`: The display-value of the argument. This string is what should
1533 * be displayed when creating the command syntax from the output of
1534 * `COMMAND`. If `token` is not NULL, it should also be displayed.
1535 *
1536 * Explanation of `RedisModuleCommandArgType`:
1537 *
1538 * * `REDISMODULE_ARG_TYPE_STRING`: String argument.
1539 * * `REDISMODULE_ARG_TYPE_INTEGER`: Integer argument.
1540 * * `REDISMODULE_ARG_TYPE_DOUBLE`: Double-precision float argument.
1541 * * `REDISMODULE_ARG_TYPE_KEY`: String argument representing a keyname.
1542 * * `REDISMODULE_ARG_TYPE_PATTERN`: String, but regex pattern.
1543 * * `REDISMODULE_ARG_TYPE_UNIX_TIME`: Integer, but Unix timestamp.
1544 * * `REDISMODULE_ARG_TYPE_PURE_TOKEN`: Argument doesn't have a placeholder.
1545 * It's just a token without a value. Example: the `KEEPTTL` option of the
1546 * `SET` command.
1547 * * `REDISMODULE_ARG_TYPE_ONEOF`: Used when the user can choose only one of
1548 * a few sub-arguments. Requires `subargs`. Example: the `NX` and `XX`
1549 * options of `SET`.
1550 * * `REDISMODULE_ARG_TYPE_BLOCK`: Used when one wants to group together
1551 * several sub-arguments, usually to apply something on all of them, like
1552 * making the entire group "optional". Requires `subargs`. Example: the
1553 * `LIMIT offset count` parameters in `ZRANGE`.
1554 *
1555 * Explanation of the command argument flags:
1556 *
1557 * * `REDISMODULE_CMD_ARG_OPTIONAL`: The argument is optional (like GET in
1558 * the SET command).
1559 * * `REDISMODULE_CMD_ARG_MULTIPLE`: The argument may repeat itself (like
1560 * key in DEL).
1561 * * `REDISMODULE_CMD_ARG_MULTIPLE_TOKEN`: The argument may repeat itself,
1562 * and so does its token (like `GET pattern` in SORT).
1563 *
1564 * On success REDISMODULE_OK is returned. On error REDISMODULE_ERR is returned
1565 * and `errno` is set to EINVAL if invalid info was provided or EEXIST if info
1566 * has already been set. If the info is invalid, a warning is logged explaining
1567 * which part of the info is invalid and why. */
1568int RM_SetCommandInfo(RedisModuleCommand *command, const RedisModuleCommandInfo *info) {
1569 if (!moduleValidateCommandInfo(info)) {
1570 errno = EINVAL;
1571 return REDISMODULE_ERR;
1572 }
1573
1574 struct redisCommand *cmd = command->rediscmd;
1575
1576 /* Check if any info has already been set. Overwriting info involves freeing
1577 * the old info, which is not implemented. */
1578 if (cmd->summary || cmd->complexity || cmd->since || cmd->history ||
1579 cmd->tips || cmd->args ||
1580 !(cmd->key_specs_num == 0 ||
1581 /* Allow key spec populated from legacy (first,last,step) to exist. */
1582 (cmd->key_specs_num == 1 && cmd->key_specs == cmd->key_specs_static &&
1583 cmd->key_specs[0].begin_search_type == KSPEC_BS_INDEX &&
1584 cmd->key_specs[0].find_keys_type == KSPEC_FK_RANGE))) {
1585 errno = EEXIST;
1586 return REDISMODULE_ERR;
1587 }
1588
1589 if (info->summary) cmd->summary = zstrdup(info->summary);
1590 if (info->complexity) cmd->complexity = zstrdup(info->complexity);
1591 if (info->since) cmd->since = zstrdup(info->since);
1592
1593 const RedisModuleCommandInfoVersion *version = info->version;
1594 if (info->history) {
1595 size_t count = 0;
1596 while (moduleCmdHistoryEntryAt(version, info->history, count)->since)
1597 count++;
1598 serverAssert(count < SIZE_MAX / sizeof(commandHistory));
1599 cmd->history = zmalloc(sizeof(commandHistory) * (count + 1));
1600 for (size_t j = 0; j < count; j++) {
1601 RedisModuleCommandHistoryEntry *entry =
1602 moduleCmdHistoryEntryAt(version, info->history, j);
1603 cmd->history[j].since = zstrdup(entry->since);
1604 cmd->history[j].changes = zstrdup(entry->changes);
1605 }
1606 cmd->history[count].since = NULL;
1607 cmd->history[count].changes = NULL;
1608 cmd->num_history = count;
1609 }
1610
1611 if (info->tips) {
1612 int count;
1613 sds *tokens = sdssplitlen(info->tips, strlen(info->tips), " ", 1, &count);
1614 if (tokens) {
1615 cmd->tips = zmalloc(sizeof(char *) * (count + 1));
1616 for (int j = 0; j < count; j++) {
1617 cmd->tips[j] = zstrdup(tokens[j]);
1618 }
1619 cmd->tips[count] = NULL;
1620 cmd->num_tips = count;
1621 sdsfreesplitres(tokens, count);
1622 }
1623 }
1624
1625 if (info->arity) cmd->arity = info->arity;
1626
1627 if (info->key_specs) {
1628 /* Count and allocate the key specs. */
1629 size_t count = 0;
1630 while (moduleCmdKeySpecAt(version, info->key_specs, count)->begin_search_type)
1631 count++;
1632 serverAssert(count < INT_MAX);
1633 if (count <= STATIC_KEY_SPECS_NUM) {
1634 cmd->key_specs_max = STATIC_KEY_SPECS_NUM;
1635 cmd->key_specs = cmd->key_specs_static;
1636 } else {
1637 cmd->key_specs_max = count;
1638 cmd->key_specs = zmalloc(sizeof(keySpec) * count);
1639 }
1640
1641 /* Copy the contents of the RedisModuleCommandKeySpec array. */
1642 cmd->key_specs_num = count;
1643 for (size_t j = 0; j < count; j++) {
1644 RedisModuleCommandKeySpec *spec =
1645 moduleCmdKeySpecAt(version, info->key_specs, j);
1646 cmd->key_specs[j].notes = spec->notes ? zstrdup(spec->notes) : NULL;
1647 cmd->key_specs[j].flags = moduleConvertKeySpecsFlags(spec->flags, 1);
1648 switch (spec->begin_search_type) {
1649 case REDISMODULE_KSPEC_BS_UNKNOWN:
1650 cmd->key_specs[j].begin_search_type = KSPEC_BS_UNKNOWN;
1651 break;
1652 case REDISMODULE_KSPEC_BS_INDEX:
1653 cmd->key_specs[j].begin_search_type = KSPEC_BS_INDEX;
1654 cmd->key_specs[j].bs.index.pos = spec->bs.index.pos;
1655 break;
1656 case REDISMODULE_KSPEC_BS_KEYWORD:
1657 cmd->key_specs[j].begin_search_type = KSPEC_BS_KEYWORD;
1658 cmd->key_specs[j].bs.keyword.keyword = zstrdup(spec->bs.keyword.keyword);
1659 cmd->key_specs[j].bs.keyword.startfrom = spec->bs.keyword.startfrom;
1660 break;
1661 default:
1662 /* Can't happen; stopped in moduleValidateCommandInfo(). */
1663 serverPanic("Unknown begin_search_type");
1664 }
1665
1666 switch (spec->find_keys_type) {
1667 case REDISMODULE_KSPEC_FK_OMITTED:
1668 /* Omitted field is shorthand to say that it's a single key. */
1669 cmd->key_specs[j].find_keys_type = KSPEC_FK_RANGE;
1670 cmd->key_specs[j].fk.range.lastkey = 0;
1671 cmd->key_specs[j].fk.range.keystep = 1;
1672 cmd->key_specs[j].fk.range.limit = 0;
1673 break;
1674 case REDISMODULE_KSPEC_FK_UNKNOWN:
1675 cmd->key_specs[j].find_keys_type = KSPEC_FK_UNKNOWN;
1676 break;
1677 case REDISMODULE_KSPEC_FK_RANGE:
1678 cmd->key_specs[j].find_keys_type = KSPEC_FK_RANGE;
1679 cmd->key_specs[j].fk.range.lastkey = spec->fk.range.lastkey;
1680 cmd->key_specs[j].fk.range.keystep = spec->fk.range.keystep;
1681 cmd->key_specs[j].fk.range.limit = spec->fk.range.limit;
1682 break;
1683 case REDISMODULE_KSPEC_FK_KEYNUM:
1684 cmd->key_specs[j].find_keys_type = KSPEC_FK_KEYNUM;
1685 cmd->key_specs[j].fk.keynum.keynumidx = spec->fk.keynum.keynumidx;
1686 cmd->key_specs[j].fk.keynum.firstkey = spec->fk.keynum.firstkey;
1687 cmd->key_specs[j].fk.keynum.keystep = spec->fk.keynum.keystep;
1688 break;
1689 default:
1690 /* Can't happen; stopped in moduleValidateCommandInfo(). */
1691 serverPanic("Unknown find_keys_type");
1692 }
1693 }
1694
1695 /* Update the legacy (first,last,step) spec and "movablekeys" flag used by the COMMAND command,
1696 * by trying to "glue" consecutive range key specs. */
1697 populateCommandLegacyRangeSpec(cmd);
1698 }
1699
1700 if (info->args) {
1701 cmd->args = moduleCopyCommandArgs(info->args, version);
1702 /* Populate arg.num_args with the number of subargs, recursively */
1703 cmd->num_args = populateArgsStructure(cmd->args);
1704 }
1705
1706 /* Fields added in future versions to be added here, under conditions like
1707 * `if (info->version >= 2) { access version 2 fields here }` */
1708
1709 return REDISMODULE_OK;
1710}
1711
1712/* Returns 1 if v is a power of two, 0 otherwise. */
1713static inline int isPowerOfTwo(uint64_t v) {
1714 return v && !(v & (v - 1));
1715}
1716
1717/* Returns 1 if the command info is valid and 0 otherwise. */
1718static int moduleValidateCommandInfo(const RedisModuleCommandInfo *info) {
1719 const RedisModuleCommandInfoVersion *version = info->version;
1720 if (!version) {
1721 serverLog(LL_WARNING, "Invalid command info: version missing");
1722 return 0;
1723 }
1724
1725 /* No validation for the fields summary, complexity, since, tips (strings or
1726 * NULL) and arity (any integer). */
1727
1728 /* History: If since is set, changes must also be set. */
1729 if (info->history) {
1730 for (size_t j = 0;
1731 moduleCmdHistoryEntryAt(version, info->history, j)->since;
1732 j++)
1733 {
1734 if (!moduleCmdHistoryEntryAt(version, info->history, j)->changes) {
1735 serverLog(LL_WARNING, "Invalid command info: history[%zd].changes missing", j);
1736 return 0;
1737 }
1738 }
1739 }
1740
1741 /* Key specs. */
1742 if (info->key_specs) {
1743 for (size_t j = 0;
1744 moduleCmdKeySpecAt(version, info->key_specs, j)->begin_search_type;
1745 j++)
1746 {
1747 RedisModuleCommandKeySpec *spec =
1748 moduleCmdKeySpecAt(version, info->key_specs, j);
1749 if (j >= INT_MAX) {
1750 serverLog(LL_WARNING, "Invalid command info: Too many key specs");
1751 return 0; /* redisCommand.key_specs_num is an int. */
1752 }
1753
1754 /* Flags. Exactly one flag in a group is set if and only if the
1755 * masked bits is a power of two. */
1756 uint64_t key_flags =
1757 REDISMODULE_CMD_KEY_RO | REDISMODULE_CMD_KEY_RW |
1758 REDISMODULE_CMD_KEY_OW | REDISMODULE_CMD_KEY_RM;
1759 uint64_t write_flags =
1760 REDISMODULE_CMD_KEY_INSERT | REDISMODULE_CMD_KEY_DELETE |
1761 REDISMODULE_CMD_KEY_UPDATE;
1762 if (!isPowerOfTwo(spec->flags & key_flags)) {
1763 serverLog(LL_WARNING,
1764 "Invalid command info: key_specs[%zd].flags: "
1765 "Exactly one of the flags RO, RW, OW, RM required", j);
1766 return 0;
1767 }
1768 if ((spec->flags & write_flags) != 0 &&
1769 !isPowerOfTwo(spec->flags & write_flags))
1770 {
1771 serverLog(LL_WARNING,
1772 "Invalid command info: key_specs[%zd].flags: "
1773 "INSERT, DELETE and UPDATE are mutually exclusive", j);
1774 return 0;
1775 }
1776
1777 switch (spec->begin_search_type) {
1778 case REDISMODULE_KSPEC_BS_UNKNOWN: break;
1779 case REDISMODULE_KSPEC_BS_INDEX: break;
1780 case REDISMODULE_KSPEC_BS_KEYWORD:
1781 if (spec->bs.keyword.keyword == NULL) {
1782 serverLog(LL_WARNING,
1783 "Invalid command info: key_specs[%zd].bs.keyword.keyword "
1784 "required when begin_search_type is KEYWORD", j);
1785 return 0;
1786 }
1787 break;
1788 default:
1789 serverLog(LL_WARNING,
1790 "Invalid command info: key_specs[%zd].begin_search_type: "
1791 "Invalid value %d", j, spec->begin_search_type);
1792 return 0;
1793 }
1794
1795 /* Validate find_keys_type. */
1796 switch (spec->find_keys_type) {
1797 case REDISMODULE_KSPEC_FK_OMITTED: break; /* short for RANGE {0,1,0} */
1798 case REDISMODULE_KSPEC_FK_UNKNOWN: break;
1799 case REDISMODULE_KSPEC_FK_RANGE: break;
1800 case REDISMODULE_KSPEC_FK_KEYNUM: break;
1801 default:
1802 serverLog(LL_WARNING,
1803 "Invalid command info: key_specs[%zd].find_keys_type: "
1804 "Invalid value %d", j, spec->find_keys_type);
1805 return 0;
1806 }
1807 }
1808 }
1809
1810 /* Args, subargs (recursive) */
1811 return moduleValidateCommandArgs(info->args, version);
1812}
1813
1814/* When from_api is true, converts from REDISMODULE_CMD_KEY_* flags to CMD_KEY_* flags.
1815 * When from_api is false, converts from CMD_KEY_* flags to REDISMODULE_CMD_KEY_* flags. */
1816static int64_t moduleConvertKeySpecsFlags(int64_t flags, int from_api) {
1817 int64_t out = 0;
1818 int64_t map[][2] = {
1819 {REDISMODULE_CMD_KEY_RO, CMD_KEY_RO},
1820 {REDISMODULE_CMD_KEY_RW, CMD_KEY_RW},
1821 {REDISMODULE_CMD_KEY_OW, CMD_KEY_OW},
1822 {REDISMODULE_CMD_KEY_RM, CMD_KEY_RM},
1823 {REDISMODULE_CMD_KEY_ACCESS, CMD_KEY_ACCESS},
1824 {REDISMODULE_CMD_KEY_INSERT, CMD_KEY_INSERT},
1825 {REDISMODULE_CMD_KEY_UPDATE, CMD_KEY_UPDATE},
1826 {REDISMODULE_CMD_KEY_DELETE, CMD_KEY_DELETE},
1827 {REDISMODULE_CMD_KEY_NOT_KEY, CMD_KEY_NOT_KEY},
1828 {REDISMODULE_CMD_KEY_INCOMPLETE, CMD_KEY_INCOMPLETE},
1829 {REDISMODULE_CMD_KEY_VARIABLE_FLAGS, CMD_KEY_VARIABLE_FLAGS},
1830 {0,0}};
1831
1832 int from_idx = from_api ? 0 : 1, to_idx = !from_idx;
1833 for (int i=0; map[i][0]; i++)
1834 if (flags & map[i][from_idx]) out |= map[i][to_idx];
1835 return out;
1836}
1837
1838/* Validates an array of RedisModuleCommandArg. Returns 1 if it's valid and 0 if
1839 * it's invalid. */
1840static int moduleValidateCommandArgs(RedisModuleCommandArg *args,
1841 const RedisModuleCommandInfoVersion *version) {
1842 if (args == NULL) return 1; /* Missing args is OK. */
1843 for (size_t j = 0; moduleCmdArgAt(version, args, j)->name != NULL; j++) {
1844 RedisModuleCommandArg *arg = moduleCmdArgAt(version, args, j);
1845 int arg_type_error = 0;
1846 moduleConvertArgType(arg->type, &arg_type_error);
1847 if (arg_type_error) {
1848 serverLog(LL_WARNING,
1849 "Invalid command info: Argument \"%s\": Undefined type %d",
1850 arg->name, arg->type);
1851 return 0;
1852 }
1853 if (arg->type == REDISMODULE_ARG_TYPE_PURE_TOKEN && !arg->token) {
1854 serverLog(LL_WARNING,
1855 "Invalid command info: Argument \"%s\": "
1856 "token required when type is PURE_TOKEN", args[j].name);
1857 return 0;
1858 }
1859
1860 if (arg->type == REDISMODULE_ARG_TYPE_KEY) {
1861 if (arg->key_spec_index < 0) {
1862 serverLog(LL_WARNING,
1863 "Invalid command info: Argument \"%s\": "
1864 "key_spec_index required when type is KEY",
1865 arg->name);
1866 return 0;
1867 }
1868 } else if (arg->key_spec_index != -1 && arg->key_spec_index != 0) {
1869 /* 0 is allowed for convenience, to allow it to be omitted in
1870 * compound struct literals on the form `.field = value`. */
1871 serverLog(LL_WARNING,
1872 "Invalid command info: Argument \"%s\": "
1873 "key_spec_index specified but type isn't KEY",
1874 arg->name);
1875 return 0;
1876 }
1877
1878 if (arg->flags & ~(_REDISMODULE_CMD_ARG_NEXT - 1)) {
1879 serverLog(LL_WARNING,
1880 "Invalid command info: Argument \"%s\": Invalid flags",
1881 arg->name);
1882 return 0;
1883 }
1884
1885 if (arg->type == REDISMODULE_ARG_TYPE_ONEOF ||
1886 arg->type == REDISMODULE_ARG_TYPE_BLOCK)
1887 {
1888 if (arg->subargs == NULL) {
1889 serverLog(LL_WARNING,
1890 "Invalid command info: Argument \"%s\": "
1891 "subargs required when type is ONEOF or BLOCK",
1892 arg->name);
1893 return 0;
1894 }
1895 if (!moduleValidateCommandArgs(arg->subargs, version)) return 0;
1896 } else {
1897 if (arg->subargs != NULL) {
1898 serverLog(LL_WARNING,
1899 "Invalid command info: Argument \"%s\": "
1900 "subargs specified but type isn't ONEOF nor BLOCK",
1901 arg->name);
1902 return 0;
1903 }
1904 }
1905 }
1906 return 1;
1907}
1908
1909/* Converts an array of RedisModuleCommandArg into a freshly allocated array of
1910 * struct redisCommandArg. */
1911static struct redisCommandArg *moduleCopyCommandArgs(RedisModuleCommandArg *args,
1912 const RedisModuleCommandInfoVersion *version) {
1913 size_t count = 0;
1914 while (moduleCmdArgAt(version, args, count)->name) count++;
1915 serverAssert(count < SIZE_MAX / sizeof(struct redisCommandArg));
1916 struct redisCommandArg *realargs = zcalloc((count+1) * sizeof(redisCommandArg));
1917
1918 for (size_t j = 0; j < count; j++) {
1919 RedisModuleCommandArg *arg = moduleCmdArgAt(version, args, j);
1920 realargs[j].name = zstrdup(arg->name);
1921 realargs[j].type = moduleConvertArgType(arg->type, NULL);
1922 if (arg->type == REDISMODULE_ARG_TYPE_KEY)
1923 realargs[j].key_spec_index = arg->key_spec_index;
1924 else
1925 realargs[j].key_spec_index = -1;
1926 if (arg->token) realargs[j].token = zstrdup(arg->token);
1927 if (arg->summary) realargs[j].summary = zstrdup(arg->summary);
1928 if (arg->since) realargs[j].since = zstrdup(arg->since);
1929 if (arg->deprecated_since) realargs[j].deprecated_since = zstrdup(arg->deprecated_since);
1930 realargs[j].flags = moduleConvertArgFlags(arg->flags);
1931 if (arg->subargs) realargs[j].subargs = moduleCopyCommandArgs(arg->subargs, version);
1932 }
1933 return realargs;
1934}
1935
1936static redisCommandArgType moduleConvertArgType(RedisModuleCommandArgType type, int *error) {
1937 if (error) *error = 0;
1938 switch (type) {
1939 case REDISMODULE_ARG_TYPE_STRING: return ARG_TYPE_STRING;
1940 case REDISMODULE_ARG_TYPE_INTEGER: return ARG_TYPE_INTEGER;
1941 case REDISMODULE_ARG_TYPE_DOUBLE: return ARG_TYPE_DOUBLE;
1942 case REDISMODULE_ARG_TYPE_KEY: return ARG_TYPE_KEY;
1943 case REDISMODULE_ARG_TYPE_PATTERN: return ARG_TYPE_PATTERN;
1944 case REDISMODULE_ARG_TYPE_UNIX_TIME: return ARG_TYPE_UNIX_TIME;
1945 case REDISMODULE_ARG_TYPE_PURE_TOKEN: return ARG_TYPE_PURE_TOKEN;
1946 case REDISMODULE_ARG_TYPE_ONEOF: return ARG_TYPE_ONEOF;
1947 case REDISMODULE_ARG_TYPE_BLOCK: return ARG_TYPE_BLOCK;
1948 default:
1949 if (error) *error = 1;
1950 return -1;
1951 }
1952}
1953
1954static int moduleConvertArgFlags(int flags) {
1955 int realflags = 0;
1956 if (flags & REDISMODULE_CMD_ARG_OPTIONAL) realflags |= CMD_ARG_OPTIONAL;
1957 if (flags & REDISMODULE_CMD_ARG_MULTIPLE) realflags |= CMD_ARG_MULTIPLE;
1958 if (flags & REDISMODULE_CMD_ARG_MULTIPLE_TOKEN) realflags |= CMD_ARG_MULTIPLE_TOKEN;
1959 return realflags;
1960}
1961
1962/* Return `struct RedisModule *` as `void *` to avoid exposing it outside of module.c. */
1963void *moduleGetHandleByName(char *modulename) {
1964 return dictFetchValue(modules,modulename);
1965}
1966
1967/* Returns 1 if `cmd` is a command of the module `modulename`. 0 otherwise. */
1968int moduleIsModuleCommand(void *module_handle, struct redisCommand *cmd) {
1969 if (cmd->proc != RedisModuleCommandDispatcher)
1970 return 0;
1971 if (module_handle == NULL)
1972 return 0;
1973 RedisModuleCommand *cp = cmd->module_cmd;
1974 return (cp->module == module_handle);
1975}
1976
1977/* --------------------------------------------------------------------------
1978 * ## Module information and time measurement
1979 * -------------------------------------------------------------------------- */
1980
1981int moduleListConfigMatch(void *config, void *name) {
1982 return strcasecmp(((ModuleConfig *) config)->name, (char *) name) == 0;
1983}
1984
1985void moduleListFree(void *config) {
1986 ModuleConfig *module_config = (ModuleConfig *) config;
1987 sdsfree(module_config->name);
1988 zfree(config);
1989}
1990
1991void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int apiver) {
1992 /* Called by RM_Init() to setup the `ctx->module` structure.
1993 *
1994 * This is an internal function, Redis modules developers don't need
1995 * to use it. */
1996 RedisModule *module;
1997
1998 if (ctx->module != NULL) return;
1999 module = zmalloc(sizeof(*module));
2000 module->name = sdsnew(name);
2001 module->ver = ver;
2002 module->apiver = apiver;
2003 module->types = listCreate();
2004 module->usedby = listCreate();
2005 module->using = listCreate();
2006 module->filters = listCreate();
2007 module->module_configs = listCreate();
2008 listSetMatchMethod(module->module_configs, moduleListConfigMatch);
2009 listSetFreeMethod(module->module_configs, moduleListFree);
2010 module->in_call = 0;
2011 module->configs_initialized = 0;
2012 module->in_hook = 0;
2013 module->options = 0;
2014 module->info_cb = 0;
2015 module->defrag_cb = 0;
2016 module->loadmod = NULL;
2017 ctx->module = module;
2018}
2019
2020/* Return non-zero if the module name is busy.
2021 * Otherwise zero is returned. */
2022int RM_IsModuleNameBusy(const char *name) {
2023 sds modulename = sdsnew(name);
2024 dictEntry *de = dictFind(modules,modulename);
2025 sdsfree(modulename);
2026 return de != NULL;
2027}
2028
2029/* Return the current UNIX time in milliseconds. */
2030long long RM_Milliseconds(void) {
2031 return mstime();
2032}
2033
2034/* Return counter of micro-seconds relative to an arbitrary point in time. */
2035uint64_t RM_MonotonicMicroseconds(void) {
2036 return getMonotonicUs();
2037}
2038
2039/* Mark a point in time that will be used as the start time to calculate
2040 * the elapsed execution time when RM_BlockedClientMeasureTimeEnd() is called.
2041 * Within the same command, you can call multiple times
2042 * RM_BlockedClientMeasureTimeStart() and RM_BlockedClientMeasureTimeEnd()
2043 * to accumulate independent time intervals to the background duration.
2044 * This method always return REDISMODULE_OK. */
2045int RM_BlockedClientMeasureTimeStart(RedisModuleBlockedClient *bc) {
2046 elapsedStart(&(bc->background_timer));
2047 return REDISMODULE_OK;
2048}
2049
2050/* Mark a point in time that will be used as the end time
2051 * to calculate the elapsed execution time.
2052 * On success REDISMODULE_OK is returned.
2053 * This method only returns REDISMODULE_ERR if no start time was
2054 * previously defined ( meaning RM_BlockedClientMeasureTimeStart was not called ). */
2055int RM_BlockedClientMeasureTimeEnd(RedisModuleBlockedClient *bc) {
2056 // If the counter is 0 then we haven't called RM_BlockedClientMeasureTimeStart
2057 if (!bc->background_timer)
2058 return REDISMODULE_ERR;
2059 bc->background_duration += elapsedUs(bc->background_timer);
2060 return REDISMODULE_OK;
2061}
2062
2063/* This API allows modules to let Redis process background tasks, and some
2064 * commands during long blocking execution of a module command.
2065 * The module can call this API periodically.
2066 * The flags is a bit mask of these:
2067 *
2068 * - `REDISMODULE_YIELD_FLAG_NONE`: No special flags, can perform some background
2069 * operations, but not process client commands.
2070 * - `REDISMODULE_YIELD_FLAG_CLIENTS`: Redis can also process client commands.
2071 *
2072 * The `busy_reply` argument is optional, and can be used to control the verbose
2073 * error string after the `-BUSY` error code.
2074 *
2075 * When the `REDISMODULE_YIELD_FLAG_CLIENTS` is used, Redis will only start
2076 * processing client commands after the time defined by the
2077 * `busy-reply-threshold` config, in which case Redis will start rejecting most
2078 * commands with `-BUSY` error, but allow the ones marked with the `allow-busy`
2079 * flag to be executed.
2080 * This API can also be used in thread safe context (while locked), and during
2081 * loading (in the `rdb_load` callback, in which case it'll reject commands with
2082 * the -LOADING error)
2083 */
2084void RM_Yield(RedisModuleCtx *ctx, int flags, const char *busy_reply) {
2085 static int yield_nesting = 0;
2086 /* Avoid nested calls to RM_Yield */
2087 if (yield_nesting)
2088 return;
2089 yield_nesting++;
2090
2091 long long now = getMonotonicUs();
2092 if (now >= ctx->next_yield_time) {
2093 /* In loading mode, there's no need to handle busy_module_yield_reply,
2094 * and busy_module_yield_flags, since redis is anyway rejecting all
2095 * commands with -LOADING. */
2096 if (server.loading) {
2097 /* Let redis process events */
2098 processEventsWhileBlocked();
2099 } else {
2100 const char *prev_busy_module_yield_reply = server.busy_module_yield_reply;
2101 server.busy_module_yield_reply = busy_reply;
2102 /* start the blocking operation if not already started. */
2103 if (!server.busy_module_yield_flags) {
2104 server.busy_module_yield_flags = BUSY_MODULE_YIELD_EVENTS;
2105 blockingOperationStarts();
2106 if (server.current_client)
2107 protectClient(server.current_client);
2108 }
2109 if (flags & REDISMODULE_YIELD_FLAG_CLIENTS)
2110 server.busy_module_yield_flags |= BUSY_MODULE_YIELD_CLIENTS;
2111
2112 /* Let redis process events */
2113 processEventsWhileBlocked();
2114
2115 server.busy_module_yield_reply = prev_busy_module_yield_reply;
2116 /* Possibly restore the previous flags in case of two nested contexts
2117 * that use this API with different flags, but keep the first bit
2118 * (PROCESS_EVENTS) set, so we know to call blockingOperationEnds on time. */
2119 server.busy_module_yield_flags &= ~BUSY_MODULE_YIELD_CLIENTS;
2120 }
2121
2122 /* decide when the next event should fire. */
2123 ctx->next_yield_time = now + 1000000 / server.hz;
2124 }
2125 yield_nesting--;
2126}
2127
2128/* Set flags defining capabilities or behavior bit flags.
2129 *
2130 * REDISMODULE_OPTIONS_HANDLE_IO_ERRORS:
2131 * Generally, modules don't need to bother with this, as the process will just
2132 * terminate if a read error happens, however, setting this flag would allow
2133 * repl-diskless-load to work if enabled.
2134 * The module should use RedisModule_IsIOError after reads, before using the
2135 * data that was read, and in case of error, propagate it upwards, and also be
2136 * able to release the partially populated value and all it's allocations.
2137 *
2138 * REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED:
2139 * See RM_SignalModifiedKey().
2140 *
2141 * REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD:
2142 * Setting this flag indicates module awareness of diskless async replication (repl-diskless-load=swapdb)
2143 * and that redis could be serving reads during replication instead of blocking with LOADING status.
2144 */
2145void RM_SetModuleOptions(RedisModuleCtx *ctx, int options) {
2146 ctx->module->options = options;
2147}
2148
2149/* Signals that the key is modified from user's perspective (i.e. invalidate WATCH
2150 * and client side caching).
2151 *
2152 * This is done automatically when a key opened for writing is closed, unless
2153 * the option REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED has been set using
2154 * RM_SetModuleOptions().
2155*/
2156int RM_SignalModifiedKey(RedisModuleCtx *ctx, RedisModuleString *keyname) {
2157 signalModifiedKey(ctx->client,ctx->client->db,keyname);
2158 return REDISMODULE_OK;
2159}
2160
2161/* --------------------------------------------------------------------------
2162 * ## Automatic memory management for modules
2163 * -------------------------------------------------------------------------- */
2164
2165/* Enable automatic memory management.
2166 *
2167 * The function must be called as the first function of a command implementation
2168 * that wants to use automatic memory.
2169 *
2170 * When enabled, automatic memory management tracks and automatically frees
2171 * keys, call replies and Redis string objects once the command returns. In most
2172 * cases this eliminates the need of calling the following functions:
2173 *
2174 * 1. RedisModule_CloseKey()
2175 * 2. RedisModule_FreeCallReply()
2176 * 3. RedisModule_FreeString()
2177 *
2178 * These functions can still be used with automatic memory management enabled,
2179 * to optimize loops that make numerous allocations for example. */
2180void RM_AutoMemory(RedisModuleCtx *ctx) {
2181 ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY;
2182}
2183
2184/* Add a new object to release automatically when the callback returns. */
2185void autoMemoryAdd(RedisModuleCtx *ctx, int type, void *ptr) {
2186 if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
2187 if (ctx->amqueue_used == ctx->amqueue_len) {
2188 ctx->amqueue_len *= 2;
2189 if (ctx->amqueue_len < 16) ctx->amqueue_len = 16;
2190 ctx->amqueue = zrealloc(ctx->amqueue,sizeof(struct AutoMemEntry)*ctx->amqueue_len);
2191 }
2192 ctx->amqueue[ctx->amqueue_used].type = type;
2193 ctx->amqueue[ctx->amqueue_used].ptr = ptr;
2194 ctx->amqueue_used++;
2195}
2196
2197/* Mark an object as freed in the auto release queue, so that users can still
2198 * free things manually if they want.
2199 *
2200 * The function returns 1 if the object was actually found in the auto memory
2201 * pool, otherwise 0 is returned. */
2202int autoMemoryFreed(RedisModuleCtx *ctx, int type, void *ptr) {
2203 if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return 0;
2204
2205 int count = (ctx->amqueue_used+1)/2;
2206 for (int j = 0; j < count; j++) {
2207 for (int side = 0; side < 2; side++) {
2208 /* For side = 0 check right side of the array, for
2209 * side = 1 check the left side instead (zig-zag scanning). */
2210 int i = (side == 0) ? (ctx->amqueue_used - 1 - j) : j;
2211 if (ctx->amqueue[i].type == type &&
2212 ctx->amqueue[i].ptr == ptr)
2213 {
2214 ctx->amqueue[i].type = REDISMODULE_AM_FREED;
2215
2216 /* Switch the freed element and the last element, to avoid growing
2217 * the queue unnecessarily if we allocate/free in a loop */
2218 if (i != ctx->amqueue_used-1) {
2219 ctx->amqueue[i] = ctx->amqueue[ctx->amqueue_used-1];
2220 }
2221
2222 /* Reduce the size of the queue because we either moved the top
2223 * element elsewhere or freed it */
2224 ctx->amqueue_used--;
2225 return 1;
2226 }
2227 }
2228 }
2229 return 0;
2230}
2231
2232/* Release all the objects in queue. */
2233void autoMemoryCollect(RedisModuleCtx *ctx) {
2234 if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
2235 /* Clear the AUTO_MEMORY flag from the context, otherwise the functions
2236 * we call to free the resources, will try to scan the auto release
2237 * queue to mark the entries as freed. */
2238 ctx->flags &= ~REDISMODULE_CTX_AUTO_MEMORY;
2239 int j;
2240 for (j = 0; j < ctx->amqueue_used; j++) {
2241 void *ptr = ctx->amqueue[j].ptr;
2242 switch(ctx->amqueue[j].type) {
2243 case REDISMODULE_AM_STRING: decrRefCount(ptr); break;
2244 case REDISMODULE_AM_REPLY: RM_FreeCallReply(ptr); break;
2245 case REDISMODULE_AM_KEY: RM_CloseKey(ptr); break;
2246 case REDISMODULE_AM_DICT: RM_FreeDict(NULL,ptr); break;
2247 case REDISMODULE_AM_INFO: RM_FreeServerInfo(NULL,ptr); break;
2248 }
2249 }
2250 ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY;
2251 zfree(ctx->amqueue);
2252 ctx->amqueue = NULL;
2253 ctx->amqueue_len = 0;
2254 ctx->amqueue_used = 0;
2255}
2256
2257/* --------------------------------------------------------------------------
2258 * ## String objects APIs
2259 * -------------------------------------------------------------------------- */
2260
2261/* Create a new module string object. The returned string must be freed
2262 * with RedisModule_FreeString(), unless automatic memory is enabled.
2263 *
2264 * The string is created by copying the `len` bytes starting
2265 * at `ptr`. No reference is retained to the passed buffer.
2266 *
2267 * The module context 'ctx' is optional and may be NULL if you want to create
2268 * a string out of the context scope. However in that case, the automatic
2269 * memory management will not be available, and the string memory must be
2270 * managed manually. */
2271RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len) {
2272 RedisModuleString *o = createStringObject(ptr,len);
2273 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
2274 return o;
2275}
2276
2277/* Create a new module string object from a printf format and arguments.
2278 * The returned string must be freed with RedisModule_FreeString(), unless
2279 * automatic memory is enabled.
2280 *
2281 * The string is created using the sds formatter function sdscatvprintf().
2282 *
2283 * The passed context 'ctx' may be NULL if necessary, see the
2284 * RedisModule_CreateString() documentation for more info. */
2285RedisModuleString *RM_CreateStringPrintf(RedisModuleCtx *ctx, const char *fmt, ...) {
2286 sds s = sdsempty();
2287
2288 va_list ap;
2289 va_start(ap, fmt);
2290 s = sdscatvprintf(s, fmt, ap);
2291 va_end(ap);
2292
2293 RedisModuleString *o = createObject(OBJ_STRING, s);
2294 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
2295
2296 return o;
2297}
2298
2299
2300/* Like RedisModule_CreateString(), but creates a string starting from a `long long`
2301 * integer instead of taking a buffer and its length.
2302 *
2303 * The returned string must be released with RedisModule_FreeString() or by
2304 * enabling automatic memory management.
2305 *
2306 * The passed context 'ctx' may be NULL if necessary, see the
2307 * RedisModule_CreateString() documentation for more info. */
2308RedisModuleString *RM_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll) {
2309 char buf[LONG_STR_SIZE];
2310 size_t len = ll2string(buf,sizeof(buf),ll);
2311 return RM_CreateString(ctx,buf,len);
2312}
2313
2314/* Like RedisModule_CreateString(), but creates a string starting from a `unsigned long long`
2315 * integer instead of taking a buffer and its length.
2316 *
2317 * The returned string must be released with RedisModule_FreeString() or by
2318 * enabling automatic memory management.
2319 *
2320 * The passed context 'ctx' may be NULL if necessary, see the
2321 * RedisModule_CreateString() documentation for more info. */
2322RedisModuleString *RM_CreateStringFromULongLong(RedisModuleCtx *ctx, unsigned long long ull) {
2323 char buf[LONG_STR_SIZE];
2324 size_t len = ull2string(buf,sizeof(buf),ull);
2325 return RM_CreateString(ctx,buf,len);
2326}
2327
2328/* Like RedisModule_CreateString(), but creates a string starting from a double
2329 * instead of taking a buffer and its length.
2330 *
2331 * The returned string must be released with RedisModule_FreeString() or by
2332 * enabling automatic memory management. */
2333RedisModuleString *RM_CreateStringFromDouble(RedisModuleCtx *ctx, double d) {
2334 char buf[MAX_D2STRING_CHARS];
2335 size_t len = d2string(buf,sizeof(buf),d);
2336 return RM_CreateString(ctx,buf,len);
2337}
2338
2339/* Like RedisModule_CreateString(), but creates a string starting from a long
2340 * double.
2341 *
2342 * The returned string must be released with RedisModule_FreeString() or by
2343 * enabling automatic memory management.
2344 *
2345 * The passed context 'ctx' may be NULL if necessary, see the
2346 * RedisModule_CreateString() documentation for more info. */
2347RedisModuleString *RM_CreateStringFromLongDouble(RedisModuleCtx *ctx, long double ld, int humanfriendly) {
2348 char buf[MAX_LONG_DOUBLE_CHARS];
2349 size_t len = ld2string(buf,sizeof(buf),ld,
2350 (humanfriendly ? LD_STR_HUMAN : LD_STR_AUTO));
2351 return RM_CreateString(ctx,buf,len);
2352}
2353
2354/* Like RedisModule_CreateString(), but creates a string starting from another
2355 * RedisModuleString.
2356 *
2357 * The returned string must be released with RedisModule_FreeString() or by
2358 * enabling automatic memory management.
2359 *
2360 * The passed context 'ctx' may be NULL if necessary, see the
2361 * RedisModule_CreateString() documentation for more info. */
2362RedisModuleString *RM_CreateStringFromString(RedisModuleCtx *ctx, const RedisModuleString *str) {
2363 RedisModuleString *o = dupStringObject(str);
2364 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
2365 return o;
2366}
2367
2368/* Creates a string from a stream ID. The returned string must be released with
2369 * RedisModule_FreeString(), unless automatic memory is enabled.
2370 *
2371 * The passed context `ctx` may be NULL if necessary. See the
2372 * RedisModule_CreateString() documentation for more info. */
2373RedisModuleString *RM_CreateStringFromStreamID(RedisModuleCtx *ctx, const RedisModuleStreamID *id) {
2374 streamID streamid = {id->ms, id->seq};
2375 RedisModuleString *o = createObjectFromStreamID(&streamid);
2376 if (ctx != NULL) autoMemoryAdd(ctx, REDISMODULE_AM_STRING, o);
2377 return o;
2378}
2379
2380/* Free a module string object obtained with one of the Redis modules API calls
2381 * that return new string objects.
2382 *
2383 * It is possible to call this function even when automatic memory management
2384 * is enabled. In that case the string will be released ASAP and removed
2385 * from the pool of string to release at the end.
2386 *
2387 * If the string was created with a NULL context 'ctx', it is also possible to
2388 * pass ctx as NULL when releasing the string (but passing a context will not
2389 * create any issue). Strings created with a context should be freed also passing
2390 * the context, so if you want to free a string out of context later, make sure
2391 * to create it using a NULL context. */
2392void RM_FreeString(RedisModuleCtx *ctx, RedisModuleString *str) {
2393 decrRefCount(str);
2394 if (ctx != NULL) autoMemoryFreed(ctx,REDISMODULE_AM_STRING,str);
2395}
2396
2397/* Every call to this function, will make the string 'str' requiring
2398 * an additional call to RedisModule_FreeString() in order to really
2399 * free the string. Note that the automatic freeing of the string obtained
2400 * enabling modules automatic memory management counts for one
2401 * RedisModule_FreeString() call (it is just executed automatically).
2402 *
2403 * Normally you want to call this function when, at the same time
2404 * the following conditions are true:
2405 *
2406 * 1. You have automatic memory management enabled.
2407 * 2. You want to create string objects.
2408 * 3. Those string objects you create need to live *after* the callback
2409 * function(for example a command implementation) creating them returns.
2410 *
2411 * Usually you want this in order to store the created string object
2412 * into your own data structure, for example when implementing a new data
2413 * type.
2414 *
2415 * Note that when memory management is turned off, you don't need
2416 * any call to RetainString() since creating a string will always result
2417 * into a string that lives after the callback function returns, if
2418 * no FreeString() call is performed.
2419 *
2420 * It is possible to call this function with a NULL context.
2421 *
2422 * When strings are going to be retained for an extended duration, it is good
2423 * practice to also call RedisModule_TrimStringAllocation() in order to
2424 * optimize memory usage.
2425 *
2426 * Threaded modules that reference retained strings from other threads *must*
2427 * explicitly trim the allocation as soon as the string is retained. Not doing
2428 * so may result with automatic trimming which is not thread safe. */
2429void RM_RetainString(RedisModuleCtx *ctx, RedisModuleString *str) {
2430 if (ctx == NULL || !autoMemoryFreed(ctx,REDISMODULE_AM_STRING,str)) {
2431 /* Increment the string reference counting only if we can't
2432 * just remove the object from the list of objects that should
2433 * be reclaimed. Why we do that, instead of just incrementing
2434 * the refcount in any case, and let the automatic FreeString()
2435 * call at the end to bring the refcount back at the desired
2436 * value? Because this way we ensure that the object refcount
2437 * value is 1 (instead of going to 2 to be dropped later to 1)
2438 * after the call to this function. This is needed for functions
2439 * like RedisModule_StringAppendBuffer() to work. */
2440 incrRefCount(str);
2441 }
2442}
2443
2444/**
2445* This function can be used instead of RedisModule_RetainString().
2446* The main difference between the two is that this function will always
2447* succeed, whereas RedisModule_RetainString() may fail because of an
2448* assertion.
2449*
2450* The function returns a pointer to RedisModuleString, which is owned
2451* by the caller. It requires a call to RedisModule_FreeString() to free
2452* the string when automatic memory management is disabled for the context.
2453* When automatic memory management is enabled, you can either call
2454* RedisModule_FreeString() or let the automation free it.
2455*
2456* This function is more efficient than RedisModule_CreateStringFromString()
2457* because whenever possible, it avoids copying the underlying
2458* RedisModuleString. The disadvantage of using this function is that it
2459* might not be possible to use RedisModule_StringAppendBuffer() on the
2460* returned RedisModuleString.
2461*
2462* It is possible to call this function with a NULL context.
2463*
2464 * When strings are going to be held for an extended duration, it is good
2465 * practice to also call RedisModule_TrimStringAllocation() in order to
2466 * optimize memory usage.
2467 *
2468 * Threaded modules that reference held strings from other threads *must*
2469 * explicitly trim the allocation as soon as the string is held. Not doing
2470 * so may result with automatic trimming which is not thread safe. */
2471RedisModuleString* RM_HoldString(RedisModuleCtx *ctx, RedisModuleString *str) {
2472 if (str->refcount == OBJ_STATIC_REFCOUNT) {
2473 return RM_CreateStringFromString(ctx, str);
2474 }
2475
2476 incrRefCount(str);
2477 if (ctx != NULL) {
2478 /*
2479 * Put the str in the auto memory management of the ctx.
2480         * It might already be there, in this case, the ref count will
2481         * be 2 and we will decrease the ref count twice and free the
2482         * object in the auto memory free function.
2483         *
2484         * Why we can not do the same trick of just remove the object
2485         * from the auto memory (like in RM_RetainString)?
2486         * This code shows the issue:
2487         *
2488         * RM_AutoMemory(ctx);
2489         * str1 = RM_CreateString(ctx, "test", 4);
2490         * str2 = RM_HoldString(ctx, str1);
2491         * RM_FreeString(str1);
2492         * RM_FreeString(str2);
2493         *
2494         * If after the RM_HoldString we would just remove the string from
2495         * the auto memory, this example will cause access to a freed memory
2496         * on 'RM_FreeString(str2);' because the String will be free
2497         * on 'RM_FreeString(str1);'.
2498         *
2499         * So it's safer to just increase the ref count
2500         * and add the String to auto memory again.
2501         *
2502         * The limitation is that it is not possible to use RedisModule_StringAppendBuffer
2503         * on the String.
2504 */
2505 autoMemoryAdd(ctx,REDISMODULE_AM_STRING,str);
2506 }
2507 return str;
2508}
2509
2510/* Given a string module object, this function returns the string pointer
2511 * and length of the string. The returned pointer and length should only
2512 * be used for read only accesses and never modified. */
2513const char *RM_StringPtrLen(const RedisModuleString *str, size_t *len) {
2514 if (str == NULL) {
2515 const char *errmsg = "(NULL string reply referenced in module)";
2516 if (len) *len = strlen(errmsg);
2517 return errmsg;
2518 }
2519 if (len) *len = sdslen(str->ptr);
2520 return str->ptr;
2521}
2522
2523/* --------------------------------------------------------------------------
2524 * Higher level string operations
2525 * ------------------------------------------------------------------------- */
2526
2527/* Convert the string into a `long long` integer, storing it at `*ll`.
2528 * Returns REDISMODULE_OK on success. If the string can't be parsed
2529 * as a valid, strict `long long` (no spaces before/after), REDISMODULE_ERR
2530 * is returned. */
2531int RM_StringToLongLong(const RedisModuleString *str, long long *ll) {
2532 return string2ll(str->ptr,sdslen(str->ptr),ll) ? REDISMODULE_OK :
2533 REDISMODULE_ERR;
2534}
2535
2536/* Convert the string into a `unsigned long long` integer, storing it at `*ull`.
2537 * Returns REDISMODULE_OK on success. If the string can't be parsed
2538 * as a valid, strict `unsigned long long` (no spaces before/after), REDISMODULE_ERR
2539 * is returned. */
2540int RM_StringToULongLong(const RedisModuleString *str, unsigned long long *ull) {
2541 return string2ull(str->ptr,ull) ? REDISMODULE_OK : REDISMODULE_ERR;
2542}
2543
2544/* Convert the string into a double, storing it at `*d`.
2545 * Returns REDISMODULE_OK on success or REDISMODULE_ERR if the string is
2546 * not a valid string representation of a double value. */
2547int RM_StringToDouble(const RedisModuleString *str, double *d) {
2548 int retval = getDoubleFromObject(str,d);
2549 return (retval == C_OK) ? REDISMODULE_OK : REDISMODULE_ERR;
2550}
2551
2552/* Convert the string into a long double, storing it at `*ld`.
2553 * Returns REDISMODULE_OK on success or REDISMODULE_ERR if the string is
2554 * not a valid string representation of a double value. */
2555int RM_StringToLongDouble(const RedisModuleString *str, long double *ld) {
2556 int retval = string2ld(str->ptr,sdslen(str->ptr),ld);
2557 return retval ? REDISMODULE_OK : REDISMODULE_ERR;
2558}
2559
2560/* Convert the string into a stream ID, storing it at `*id`.
2561 * Returns REDISMODULE_OK on success and returns REDISMODULE_ERR if the string
2562 * is not a valid string representation of a stream ID. The special IDs "+" and
2563 * "-" are allowed.
2564 */
2565int RM_StringToStreamID(const RedisModuleString *str, RedisModuleStreamID *id) {
2566 streamID streamid;
2567 if (streamParseID(str, &streamid) == C_OK) {
2568 id->ms = streamid.ms;
2569 id->seq = streamid.seq;
2570 return REDISMODULE_OK;
2571 } else {
2572 return REDISMODULE_ERR;
2573 }
2574}
2575
2576/* Compare two string objects, returning -1, 0 or 1 respectively if
2577 * a < b, a == b, a > b. Strings are compared byte by byte as two
2578 * binary blobs without any encoding care / collation attempt. */
2579int RM_StringCompare(RedisModuleString *a, RedisModuleString *b) {
2580 return compareStringObjects(a,b);
2581}
2582
2583/* Return the (possibly modified in encoding) input 'str' object if
2584 * the string is unshared, otherwise NULL is returned. */
2585RedisModuleString *moduleAssertUnsharedString(RedisModuleString *str) {
2586 if (str->refcount != 1) {
2587 serverLog(LL_WARNING,
2588 "Module attempted to use an in-place string modify operation "
2589 "with a string referenced multiple times. Please check the code "
2590 "for API usage correctness.");
2591 return NULL;
2592 }
2593 if (str->encoding == OBJ_ENCODING_EMBSTR) {
2594 /* Note: here we "leak" the additional allocation that was
2595 * used in order to store the embedded string in the object. */
2596 str->ptr = sdsnewlen(str->ptr,sdslen(str->ptr));
2597 str->encoding = OBJ_ENCODING_RAW;
2598 } else if (str->encoding == OBJ_ENCODING_INT) {
2599 /* Convert the string from integer to raw encoding. */
2600 str->ptr = sdsfromlonglong((long)str->ptr);
2601 str->encoding = OBJ_ENCODING_RAW;
2602 }
2603 return str;
2604}
2605
2606/* Append the specified buffer to the string 'str'. The string must be a
2607 * string created by the user that is referenced only a single time, otherwise
2608 * REDISMODULE_ERR is returned and the operation is not performed. */
2609int RM_StringAppendBuffer(RedisModuleCtx *ctx, RedisModuleString *str, const char *buf, size_t len) {
2610 UNUSED(ctx);
2611 str = moduleAssertUnsharedString(str);
2612 if (str == NULL) return REDISMODULE_ERR;
2613 str->ptr = sdscatlen(str->ptr,buf,len);
2614 return REDISMODULE_OK;
2615}
2616
2617/* Trim possible excess memory allocated for a RedisModuleString.
2618 *
2619 * Sometimes a RedisModuleString may have more memory allocated for
2620 * it than required, typically for argv arguments that were constructed
2621 * from network buffers. This function optimizes such strings by reallocating
2622 * their memory, which is useful for strings that are not short lived but
2623 * retained for an extended duration.
2624 *
2625 * This operation is *not thread safe* and should only be called when
2626 * no concurrent access to the string is guaranteed. Using it for an argv
2627 * string in a module command before the string is potentially available
2628 * to other threads is generally safe.
2629 *
2630 * Currently, Redis may also automatically trim retained strings when a
2631 * module command returns. However, doing this explicitly should still be
2632 * a preferred option:
2633 *
2634 * 1. Future versions of Redis may abandon auto-trimming.
2635 * 2. Auto-trimming as currently implemented is *not thread safe*.
2636 * A background thread manipulating a recently retained string may end up
2637 * in a race condition with the auto-trim, which could result with
2638 * data corruption.
2639 */
2640void RM_TrimStringAllocation(RedisModuleString *str) {
2641 if (!str) return;
2642 trimStringObjectIfNeeded(str);
2643}
2644
2645/* --------------------------------------------------------------------------
2646 * ## Reply APIs
2647 *
2648 * These functions are used for sending replies to the client.
2649 *
2650 * Most functions always return REDISMODULE_OK so you can use it with
2651 * 'return' in order to return from the command implementation with:
2652 *
2653 * if (... some condition ...)
2654 * return RedisModule_ReplyWithLongLong(ctx,mycount);
2655 *
2656 * ### Reply with collection functions
2657 *
2658 * After starting a collection reply, the module must make calls to other
2659 * `ReplyWith*` style functions in order to emit the elements of the collection.
2660 * Collection types include: Array, Map, Set and Attribute.
2661 *
2662 * When producing collections with a number of elements that is not known
2663 * beforehand, the function can be called with a special flag
2664 * REDISMODULE_POSTPONED_LEN (REDISMODULE_POSTPONED_ARRAY_LEN in the past),
2665 * and the actual number of elements can be later set with RM_ReplySet*Length()
2666 * call (which will set the latest "open" count if there are multiple ones).
2667 * -------------------------------------------------------------------------- */
2668
2669/* Send an error about the number of arguments given to the command,
2670 * citing the command name in the error message. Returns REDISMODULE_OK.
2671 *
2672 * Example:
2673 *
2674 * if (argc != 3) return RedisModule_WrongArity(ctx);
2675 */
2676int RM_WrongArity(RedisModuleCtx *ctx) {
2677 addReplyErrorArity(ctx->client);
2678 return REDISMODULE_OK;
2679}
2680
2681/* Return the client object the `RM_Reply*` functions should target.
2682 * Normally this is just `ctx->client`, that is the client that called
2683 * the module command, however in the case of thread safe contexts there
2684 * is no directly associated client (since it would not be safe to access
2685 * the client from a thread), so instead the blocked client object referenced
2686 * in the thread safe context, has a fake client that we just use to accumulate
2687 * the replies. Later, when the client is unblocked, the accumulated replies
2688 * are appended to the actual client.
2689 *
2690 * The function returns the client pointer depending on the context, or
2691 * NULL if there is no potential client. This happens when we are in the
2692 * context of a thread safe context that was not initialized with a blocked
2693 * client object. Other contexts without associated clients are the ones
2694 * initialized to run the timers callbacks. */
2695client *moduleGetReplyClient(RedisModuleCtx *ctx) {
2696 if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) {
2697 if (ctx->blocked_client)
2698 return ctx->blocked_client->reply_client;
2699 else
2700 return NULL;
2701 } else {
2702 /* If this is a non thread safe context, just return the client
2703 * that is running the command if any. This may be NULL as well
2704 * in the case of contexts that are not executed with associated
2705 * clients, like timer contexts. */
2706 return ctx->client;
2707 }
2708}
2709
2710/* Send an integer reply to the client, with the specified `long long` value.
2711 * The function always returns REDISMODULE_OK. */
2712int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll) {
2713 client *c = moduleGetReplyClient(ctx);
2714 if (c == NULL) return REDISMODULE_OK;
2715 addReplyLongLong(c,ll);
2716 return REDISMODULE_OK;
2717}
2718
2719/* Reply with the error 'err'.
2720 *
2721 * Note that 'err' must contain all the error, including
2722 * the initial error code. The function only provides the initial "-", so
2723 * the usage is, for example:
2724 *
2725 * RedisModule_ReplyWithError(ctx,"ERR Wrong Type");
2726 *
2727 * and not just:
2728 *
2729 * RedisModule_ReplyWithError(ctx,"Wrong Type");
2730 *
2731 * The function always returns REDISMODULE_OK.
2732 */
2733int RM_ReplyWithError(RedisModuleCtx *ctx, const char *err) {
2734 client *c = moduleGetReplyClient(ctx);
2735 if (c == NULL) return REDISMODULE_OK;
2736 addReplyErrorFormat(c,"-%s",err);
2737 return REDISMODULE_OK;
2738}
2739
2740/* Reply with a simple string (`+... \r\n` in RESP protocol). This replies
2741 * are suitable only when sending a small non-binary string with small
2742 * overhead, like "OK" or similar replies.
2743 *
2744 * The function always returns REDISMODULE_OK. */
2745int RM_ReplyWithSimpleString(RedisModuleCtx *ctx, const char *msg) {
2746 client *c = moduleGetReplyClient(ctx);
2747 if (c == NULL) return REDISMODULE_OK;
2748 addReplyProto(c,"+",1);
2749 addReplyProto(c,msg,strlen(msg));
2750 addReplyProto(c,"\r\n",2);
2751 return REDISMODULE_OK;
2752}
2753
2754#define COLLECTION_REPLY_ARRAY 1
2755#define COLLECTION_REPLY_MAP 2
2756#define COLLECTION_REPLY_SET 3
2757#define COLLECTION_REPLY_ATTRIBUTE 4
2758
2759int moduleReplyWithCollection(RedisModuleCtx *ctx, long len, int type) {
2760 client *c = moduleGetReplyClient(ctx);
2761 if (c == NULL) return REDISMODULE_OK;
2762 if (len == REDISMODULE_POSTPONED_LEN) {
2763 ctx->postponed_arrays = zrealloc(ctx->postponed_arrays,sizeof(void*)*
2764 (ctx->postponed_arrays_count+1));
2765 ctx->postponed_arrays[ctx->postponed_arrays_count] =
2766 addReplyDeferredLen(c);
2767 ctx->postponed_arrays_count++;
2768 } else if (len == 0) {
2769 switch (type) {
2770 case COLLECTION_REPLY_ARRAY:
2771 addReply(c, shared.emptyarray);
2772 break;
2773 case COLLECTION_REPLY_MAP:
2774 addReply(c, shared.emptymap[c->resp]);
2775 break;
2776 case COLLECTION_REPLY_SET:
2777 addReply(c, shared.emptyset[c->resp]);
2778 break;
2779 case COLLECTION_REPLY_ATTRIBUTE:
2780 addReplyAttributeLen(c,len);
2781 break;
2782 default:
2783 serverPanic("Invalid module empty reply type %d", type); }
2784 } else {
2785 switch (type) {
2786 case COLLECTION_REPLY_ARRAY:
2787 addReplyArrayLen(c,len);
2788 break;
2789 case COLLECTION_REPLY_MAP:
2790 addReplyMapLen(c,len);
2791 break;
2792 case COLLECTION_REPLY_SET:
2793 addReplySetLen(c,len);
2794 break;
2795 case COLLECTION_REPLY_ATTRIBUTE:
2796 addReplyAttributeLen(c,len);
2797 break;
2798 default:
2799 serverPanic("Invalid module reply type %d", type);
2800 }
2801 }
2802 return REDISMODULE_OK;
2803}
2804
2805/* Reply with an array type of 'len' elements.
2806 *
2807 * After starting an array reply, the module must make `len` calls to other
2808 * `ReplyWith*` style functions in order to emit the elements of the array.
2809 * See Reply APIs section for more details.
2810 *
2811 * Use RM_ReplySetArrayLength() to set deferred length.
2812 *
2813 * The function always returns REDISMODULE_OK. */
2814int RM_ReplyWithArray(RedisModuleCtx *ctx, long len) {
2815 return moduleReplyWithCollection(ctx, len, COLLECTION_REPLY_ARRAY);
2816}
2817
2818/* Reply with a RESP3 Map type of 'len' pairs.
2819 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3.
2820 *
2821 * After starting a map reply, the module must make `len*2` calls to other
2822 * `ReplyWith*` style functions in order to emit the elements of the map.
2823 * See Reply APIs section for more details.
2824 *
2825 * If the connected client is using RESP2, the reply will be converted to a flat
2826 * array.
2827 *
2828 * Use RM_ReplySetMapLength() to set deferred length.
2829 *
2830 * The function always returns REDISMODULE_OK. */
2831int RM_ReplyWithMap(RedisModuleCtx *ctx, long len) {
2832 return moduleReplyWithCollection(ctx, len, COLLECTION_REPLY_MAP);
2833}
2834
2835/* Reply with a RESP3 Set type of 'len' elements.
2836 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3.
2837 *
2838 * After starting a set reply, the module must make `len` calls to other
2839 * `ReplyWith*` style functions in order to emit the elements of the set.
2840 * See Reply APIs section for more details.
2841 *
2842 * If the connected client is using RESP2, the reply will be converted to an
2843 * array type.
2844 *
2845 * Use RM_ReplySetSetLength() to set deferred length.
2846 *
2847 * The function always returns REDISMODULE_OK. */
2848int RM_ReplyWithSet(RedisModuleCtx *ctx, long len) {
2849 return moduleReplyWithCollection(ctx, len, COLLECTION_REPLY_SET);
2850}
2851
2852
2853/* Add attributes (metadata) to the reply. Should be done before adding the
2854 * actual reply. see https://github.com/antirez/RESP3/blob/master/spec.md#attribute-type
2855 *
2856 * After starting an attribute's reply, the module must make `len*2` calls to other
2857 * `ReplyWith*` style functions in order to emit the elements of the attribute map.
2858 * See Reply APIs section for more details.
2859 *
2860 * Use RM_ReplySetAttributeLength() to set deferred length.
2861 *
2862 * Not supported by RESP2 and will return REDISMODULE_ERR, otherwise
2863 * the function always returns REDISMODULE_OK. */
2864int RM_ReplyWithAttribute(RedisModuleCtx *ctx, long len) {
2865 if (ctx->client->resp == 2) return REDISMODULE_ERR;
2866
2867 return moduleReplyWithCollection(ctx, len, COLLECTION_REPLY_ATTRIBUTE);
2868}
2869
2870/* Reply to the client with a null array, simply null in RESP3,
2871 * null array in RESP2.
2872 *
2873 * Note: In RESP3 there's no difference between Null reply and
2874 * NullArray reply, so to prevent ambiguity it's better to avoid
2875 * using this API and use RedisModule_ReplyWithNull instead.
2876 *
2877 * The function always returns REDISMODULE_OK. */
2878int RM_ReplyWithNullArray(RedisModuleCtx *ctx) {
2879 client *c = moduleGetReplyClient(ctx);
2880 if (c == NULL) return REDISMODULE_OK;
2881 addReplyNullArray(c);
2882 return REDISMODULE_OK;
2883}
2884
2885/* Reply to the client with an empty array.
2886 *
2887 * The function always returns REDISMODULE_OK. */
2888int RM_ReplyWithEmptyArray(RedisModuleCtx *ctx) {
2889 client *c = moduleGetReplyClient(ctx);
2890 if (c == NULL) return REDISMODULE_OK;
2891 addReply(c,shared.emptyarray);
2892 return REDISMODULE_OK;
2893}
2894
2895void moduleReplySetCollectionLength(RedisModuleCtx *ctx, long len, int type) {
2896 client *c = moduleGetReplyClient(ctx);
2897 if (c == NULL) return;
2898 if (ctx->postponed_arrays_count == 0) {
2899 serverLog(LL_WARNING,
2900 "API misuse detected in module %s: "
2901 "RedisModule_ReplySet*Length() called without previous "
2902 "RedisModule_ReplyWith*(ctx,REDISMODULE_POSTPONED_LEN) "
2903 "call.", ctx->module->name);
2904 return;
2905 }
2906 ctx->postponed_arrays_count--;
2907 switch(type) {
2908 case COLLECTION_REPLY_ARRAY:
2909 setDeferredArrayLen(c,ctx->postponed_arrays[ctx->postponed_arrays_count],len);
2910 break;
2911 case COLLECTION_REPLY_MAP:
2912 setDeferredMapLen(c,ctx->postponed_arrays[ctx->postponed_arrays_count],len);
2913 break;
2914 case COLLECTION_REPLY_SET:
2915 setDeferredSetLen(c,ctx->postponed_arrays[ctx->postponed_arrays_count],len);
2916 break;
2917 case COLLECTION_REPLY_ATTRIBUTE:
2918 setDeferredAttributeLen(c,ctx->postponed_arrays[ctx->postponed_arrays_count],len);
2919 break;
2920 default:
2921 serverPanic("Invalid module reply type %d", type);
2922 }
2923 if (ctx->postponed_arrays_count == 0) {
2924 zfree(ctx->postponed_arrays);
2925 ctx->postponed_arrays = NULL;
2926 }
2927}
2928
2929/* When RedisModule_ReplyWithArray() is used with the argument
2930 * REDISMODULE_POSTPONED_LEN, because we don't know beforehand the number
2931 * of items we are going to output as elements of the array, this function
2932 * will take care to set the array length.
2933 *
2934 * Since it is possible to have multiple array replies pending with unknown
2935 * length, this function guarantees to always set the latest array length
2936 * that was created in a postponed way.
2937 *
2938 * For example in order to output an array like [1,[10,20,30]] we
2939 * could write:
2940 *
2941 * RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
2942 * RedisModule_ReplyWithLongLong(ctx,1);
2943 * RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_LEN);
2944 * RedisModule_ReplyWithLongLong(ctx,10);
2945 * RedisModule_ReplyWithLongLong(ctx,20);
2946 * RedisModule_ReplyWithLongLong(ctx,30);
2947 * RedisModule_ReplySetArrayLength(ctx,3); // Set len of 10,20,30 array.
2948 * RedisModule_ReplySetArrayLength(ctx,2); // Set len of top array
2949 *
2950 * Note that in the above example there is no reason to postpone the array
2951 * length, since we produce a fixed number of elements, but in the practice
2952 * the code may use an iterator or other ways of creating the output so
2953 * that is not easy to calculate in advance the number of elements.
2954 */
2955void RM_ReplySetArrayLength(RedisModuleCtx *ctx, long len) {
2956 moduleReplySetCollectionLength(ctx, len, COLLECTION_REPLY_ARRAY);
2957}
2958
2959/* Very similar to RedisModule_ReplySetArrayLength except `len` should
2960 * exactly half of the number of `ReplyWith*` functions called in the
2961 * context of the map.
2962 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3. */
2963void RM_ReplySetMapLength(RedisModuleCtx *ctx, long len) {
2964 moduleReplySetCollectionLength(ctx, len, COLLECTION_REPLY_MAP);
2965}
2966
2967/* Very similar to RedisModule_ReplySetArrayLength
2968 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3. */
2969void RM_ReplySetSetLength(RedisModuleCtx *ctx, long len) {
2970 moduleReplySetCollectionLength(ctx, len, COLLECTION_REPLY_SET);
2971}
2972
2973/* Very similar to RedisModule_ReplySetMapLength
2974 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3.
2975 *
2976 * Must not be called if RM_ReplyWithAttribute returned an error. */
2977void RM_ReplySetAttributeLength(RedisModuleCtx *ctx, long len) {
2978 if (ctx->client->resp == 2) return;
2979 moduleReplySetCollectionLength(ctx, len, COLLECTION_REPLY_ATTRIBUTE);
2980}
2981
2982/* Reply with a bulk string, taking in input a C buffer pointer and length.
2983 *
2984 * The function always returns REDISMODULE_OK. */
2985int RM_ReplyWithStringBuffer(RedisModuleCtx *ctx, const char *buf, size_t len) {
2986 client *c = moduleGetReplyClient(ctx);
2987 if (c == NULL) return REDISMODULE_OK;
2988 addReplyBulkCBuffer(c,(char*)buf,len);
2989 return REDISMODULE_OK;
2990}
2991
2992/* Reply with a bulk string, taking in input a C buffer pointer that is
2993 * assumed to be null-terminated.
2994 *
2995 * The function always returns REDISMODULE_OK. */
2996int RM_ReplyWithCString(RedisModuleCtx *ctx, const char *buf) {
2997 client *c = moduleGetReplyClient(ctx);
2998 if (c == NULL) return REDISMODULE_OK;
2999 addReplyBulkCString(c,(char*)buf);
3000 return REDISMODULE_OK;
3001}
3002
3003/* Reply with a bulk string, taking in input a RedisModuleString object.
3004 *
3005 * The function always returns REDISMODULE_OK. */
3006int RM_ReplyWithString(RedisModuleCtx *ctx, RedisModuleString *str) {
3007 client *c = moduleGetReplyClient(ctx);
3008 if (c == NULL) return REDISMODULE_OK;
3009 addReplyBulk(c,str);
3010 return REDISMODULE_OK;
3011}
3012
3013/* Reply with an empty string.
3014 *
3015 * The function always returns REDISMODULE_OK. */
3016int RM_ReplyWithEmptyString(RedisModuleCtx *ctx) {
3017 client *c = moduleGetReplyClient(ctx);
3018 if (c == NULL) return REDISMODULE_OK;
3019 addReply(c,shared.emptybulk);
3020 return REDISMODULE_OK;
3021}
3022
3023/* Reply with a binary safe string, which should not be escaped or filtered
3024 * taking in input a C buffer pointer, length and a 3 character type/extension.
3025 *
3026 * The function always returns REDISMODULE_OK. */
3027int RM_ReplyWithVerbatimStringType(RedisModuleCtx *ctx, const char *buf, size_t len, const char *ext) {
3028 client *c = moduleGetReplyClient(ctx);
3029 if (c == NULL) return REDISMODULE_OK;
3030 addReplyVerbatim(c, buf, len, ext);
3031 return REDISMODULE_OK;
3032}
3033
3034/* Reply with a binary safe string, which should not be escaped or filtered
3035 * taking in input a C buffer pointer and length.
3036 *
3037 * The function always returns REDISMODULE_OK. */
3038int RM_ReplyWithVerbatimString(RedisModuleCtx *ctx, const char *buf, size_t len) {
3039 return RM_ReplyWithVerbatimStringType(ctx, buf, len, "txt");
3040}
3041
3042/* Reply to the client with a NULL.
3043 *
3044 * The function always returns REDISMODULE_OK. */
3045int RM_ReplyWithNull(RedisModuleCtx *ctx) {
3046 client *c = moduleGetReplyClient(ctx);
3047 if (c == NULL) return REDISMODULE_OK;
3048 addReplyNull(c);
3049 return REDISMODULE_OK;
3050}
3051
3052/* Reply with a RESP3 Boolean type.
3053 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3.
3054 *
3055 * In RESP3, this is boolean type
3056 * In RESP2, it's a string response of "1" and "0" for true and false respectively.
3057 *
3058 * The function always returns REDISMODULE_OK. */
3059int RM_ReplyWithBool(RedisModuleCtx *ctx, int b) {
3060 client *c = moduleGetReplyClient(ctx);
3061 if (c == NULL) return REDISMODULE_OK;
3062 addReplyBool(c,b);
3063 return REDISMODULE_OK;
3064}
3065
3066/* Reply exactly what a Redis command returned us with RedisModule_Call().
3067 * This function is useful when we use RedisModule_Call() in order to
3068 * execute some command, as we want to reply to the client exactly the
3069 * same reply we obtained by the command.
3070 *
3071 * Return:
3072 * - REDISMODULE_OK on success.
3073 * - REDISMODULE_ERR if the given reply is in RESP3 format but the client expects RESP2.
3074 * In case of an error, it's the module writer responsibility to translate the reply
3075 * to RESP2 (or handle it differently by returning an error). Notice that for
3076 * module writer convenience, it is possible to pass `0` as a parameter to the fmt
3077 * argument of `RM_Call` so that the RedisModuleCallReply will return in the same
3078 * protocol (RESP2 or RESP3) as set in the current client's context. */
3079int RM_ReplyWithCallReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply) {
3080 client *c = moduleGetReplyClient(ctx);
3081 if (c == NULL) return REDISMODULE_OK;
3082 if (c->resp == 2 && callReplyIsResp3(reply)) {
3083 /* The reply is in RESP3 format and the client is RESP2,
3084 * so it isn't possible to send this reply to the client. */
3085 return REDISMODULE_ERR;
3086 }
3087 size_t proto_len;
3088 const char *proto = callReplyGetProto(reply, &proto_len);
3089 addReplyProto(c, proto, proto_len);
3090 /* Propagate the error list from that reply to the other client, to do some
3091 * post error reply handling, like statistics.
3092 * Note that if the original reply had an array with errors, and the module
3093 * replied with just a portion of the original reply, and not the entire
3094 * reply, the errors are currently not propagated and the errors stats
3095 * will not get propagated. */
3096 list *errors = callReplyDeferredErrorList(reply);
3097 if (errors)
3098 deferredAfterErrorReply(c, errors);
3099 return REDISMODULE_OK;
3100}
3101
3102/* Reply with a RESP3 Double type.
3103 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3.
3104 *
3105 * Send a string reply obtained converting the double 'd' into a bulk string.
3106 * This function is basically equivalent to converting a double into
3107 * a string into a C buffer, and then calling the function
3108 * RedisModule_ReplyWithStringBuffer() with the buffer and length.
3109 *
3110 * In RESP3 the string is tagged as a double, while in RESP2 it's just a plain string
3111 * that the user will have to parse.
3112 *
3113 * The function always returns REDISMODULE_OK. */
3114int RM_ReplyWithDouble(RedisModuleCtx *ctx, double d) {
3115 client *c = moduleGetReplyClient(ctx);
3116 if (c == NULL) return REDISMODULE_OK;
3117 addReplyDouble(c,d);
3118 return REDISMODULE_OK;
3119}
3120
3121/* Reply with a RESP3 BigNumber type.
3122 * Visit https://github.com/antirez/RESP3/blob/master/spec.md for more info about RESP3.
3123 *
3124 * In RESP3, this is a string of length `len` that is tagged as a BigNumber,
3125 * however, it's up to the caller to ensure that it's a valid BigNumber.
3126 * In RESP2, this is just a plain bulk string response.
3127 *
3128 * The function always returns REDISMODULE_OK. */
3129int RM_ReplyWithBigNumber(RedisModuleCtx *ctx, const char *bignum, size_t len) {
3130 client *c = moduleGetReplyClient(ctx);
3131 if (c == NULL) return REDISMODULE_OK;
3132 addReplyBigNum(c, bignum, len);
3133 return REDISMODULE_OK;
3134}
3135
3136/* Send a string reply obtained converting the long double 'ld' into a bulk
3137 * string. This function is basically equivalent to converting a long double
3138 * into a string into a C buffer, and then calling the function
3139 * RedisModule_ReplyWithStringBuffer() with the buffer and length.
3140 * The double string uses human readable formatting (see
3141 * `addReplyHumanLongDouble` in networking.c).
3142 *
3143 * The function always returns REDISMODULE_OK. */
3144int RM_ReplyWithLongDouble(RedisModuleCtx *ctx, long double ld) {
3145 client *c = moduleGetReplyClient(ctx);
3146 if (c == NULL) return REDISMODULE_OK;
3147 addReplyHumanLongDouble(c, ld);
3148 return REDISMODULE_OK;
3149}
3150
3151/* --------------------------------------------------------------------------
3152 * ## Commands replication API
3153 * -------------------------------------------------------------------------- */
3154
3155/* Replicate the specified command and arguments to slaves and AOF, as effect
3156 * of execution of the calling command implementation.
3157 *
3158 * The replicated commands are always wrapped into the MULTI/EXEC that
3159 * contains all the commands replicated in a given module command
3160 * execution. However the commands replicated with RedisModule_Call()
3161 * are the first items, the ones replicated with RedisModule_Replicate()
3162 * will all follow before the EXEC.
3163 *
3164 * Modules should try to use one interface or the other.
3165 *
3166 * This command follows exactly the same interface of RedisModule_Call(),
3167 * so a set of format specifiers must be passed, followed by arguments
3168 * matching the provided format specifiers.
3169 *
3170 * Please refer to RedisModule_Call() for more information.
3171 *
3172 * Using the special "A" and "R" modifiers, the caller can exclude either
3173 * the AOF or the replicas from the propagation of the specified command.
3174 * Otherwise, by default, the command will be propagated in both channels.
3175 *
3176 * #### Note about calling this function from a thread safe context:
3177 *
3178 * Normally when you call this function from the callback implementing a
3179 * module command, or any other callback provided by the Redis Module API,
3180 * Redis will accumulate all the calls to this function in the context of
3181 * the callback, and will propagate all the commands wrapped in a MULTI/EXEC
3182 * transaction. However when calling this function from a threaded safe context
3183 * that can live an undefined amount of time, and can be locked/unlocked in
3184 * at will, the behavior is different: MULTI/EXEC wrapper is not emitted
3185 * and the command specified is inserted in the AOF and replication stream
3186 * immediately.
3187 *
3188 * #### Return value
3189 *
3190 * The command returns REDISMODULE_ERR if the format specifiers are invalid
3191 * or the command name does not belong to a known command. */
3192int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
3193 struct redisCommand *cmd;
3194 robj **argv = NULL;
3195 int argc = 0, flags = 0, j;
3196 va_list ap;
3197
3198 cmd = lookupCommandByCString((char*)cmdname);
3199 if (!cmd) return REDISMODULE_ERR;
3200
3201 /* Create the client and dispatch the command. */
3202 va_start(ap, fmt);
3203 argv = moduleCreateArgvFromUserFormat(cmdname,fmt,&argc,NULL,&flags,ap);
3204 va_end(ap);
3205 if (argv == NULL) return REDISMODULE_ERR;
3206
3207 /* Select the propagation target. Usually is AOF + replicas, however
3208 * the caller can exclude one or the other using the "A" or "R"
3209 * modifiers. */
3210 int target = 0;
3211 if (!(flags & REDISMODULE_ARGV_NO_AOF)) target |= PROPAGATE_AOF;
3212 if (!(flags & REDISMODULE_ARGV_NO_REPLICAS)) target |= PROPAGATE_REPL;
3213
3214 alsoPropagate(ctx->client->db->id,argv,argc,target);
3215
3216 /* Release the argv. */
3217 for (j = 0; j < argc; j++) decrRefCount(argv[j]);
3218 zfree(argv);
3219 server.dirty++;
3220 return REDISMODULE_OK;
3221}
3222
3223/* This function will replicate the command exactly as it was invoked
3224 * by the client. Note that this function will not wrap the command into
3225 * a MULTI/EXEC stanza, so it should not be mixed with other replication
3226 * commands.
3227 *
3228 * Basically this form of replication is useful when you want to propagate
3229 * the command to the slaves and AOF file exactly as it was called, since
3230 * the command can just be re-executed to deterministically re-create the
3231 * new state starting from the old one.
3232 *
3233 * The function always returns REDISMODULE_OK. */
3234int RM_ReplicateVerbatim(RedisModuleCtx *ctx) {
3235 alsoPropagate(ctx->client->db->id,
3236 ctx->client->argv,ctx->client->argc,
3237 PROPAGATE_AOF|PROPAGATE_REPL);
3238 server.dirty++;
3239 return REDISMODULE_OK;
3240}
3241
3242/* --------------------------------------------------------------------------
3243 * ## DB and Key APIs -- Generic API
3244 * -------------------------------------------------------------------------- */
3245
3246/* Return the ID of the current client calling the currently active module
3247 * command. The returned ID has a few guarantees:
3248 *
3249 * 1. The ID is different for each different client, so if the same client
3250 * executes a module command multiple times, it can be recognized as
3251 * having the same ID, otherwise the ID will be different.
3252 * 2. The ID increases monotonically. Clients connecting to the server later
3253 * are guaranteed to get IDs greater than any past ID previously seen.
3254 *
3255 * Valid IDs are from 1 to 2^64 - 1. If 0 is returned it means there is no way
3256 * to fetch the ID in the context the function was currently called.
3257 *
3258 * After obtaining the ID, it is possible to check if the command execution
3259 * is actually happening in the context of AOF loading, using this macro:
3260 *
3261 * if (RedisModule_IsAOFClient(RedisModule_GetClientId(ctx)) {
3262 * // Handle it differently.
3263 * }
3264 */
3265unsigned long long RM_GetClientId(RedisModuleCtx *ctx) {
3266 if (ctx->client == NULL) return 0;
3267 return ctx->client->id;
3268}
3269
3270/* Return the ACL user name used by the client with the specified client ID.
3271 * Client ID can be obtained with RM_GetClientId() API. If the client does not
3272 * exist, NULL is returned and errno is set to ENOENT. If the client isn't
3273 * using an ACL user, NULL is returned and errno is set to ENOTSUP */
3274RedisModuleString *RM_GetClientUserNameById(RedisModuleCtx *ctx, uint64_t id) {
3275 client *client = lookupClientByID(id);
3276 if (client == NULL) {
3277 errno = ENOENT;
3278 return NULL;
3279 }
3280
3281 if (client->user == NULL) {
3282 errno = ENOTSUP;
3283 return NULL;
3284 }
3285
3286 sds name = sdsnew(client->user->name);
3287 robj *str = createObject(OBJ_STRING, name);
3288 autoMemoryAdd(ctx, REDISMODULE_AM_STRING, str);
3289 return str;
3290}
3291
3292/* This is a helper for RM_GetClientInfoById() and other functions: given
3293 * a client, it populates the client info structure with the appropriate
3294 * fields depending on the version provided. If the version is not valid
3295 * then REDISMODULE_ERR is returned. Otherwise the function returns
3296 * REDISMODULE_OK and the structure pointed by 'ci' gets populated. */
3297
3298int modulePopulateClientInfoStructure(void *ci, client *client, int structver) {
3299 if (structver != 1) return REDISMODULE_ERR;
3300
3301 RedisModuleClientInfoV1 *ci1 = ci;
3302 memset(ci1,0,sizeof(*ci1));
3303 ci1->version = structver;
3304 if (client->flags & CLIENT_MULTI)
3305 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_MULTI;
3306 if (client->flags & CLIENT_PUBSUB)
3307 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_PUBSUB;
3308 if (client->flags & CLIENT_UNIX_SOCKET)
3309 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET;
3310 if (client->flags & CLIENT_TRACKING)
3311 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_TRACKING;
3312 if (client->flags & CLIENT_BLOCKED)
3313 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_BLOCKED;
3314 if (connGetType(client->conn) == CONN_TYPE_TLS)
3315 ci1->flags |= REDISMODULE_CLIENTINFO_FLAG_SSL;
3316
3317 int port;
3318 connPeerToString(client->conn,ci1->addr,sizeof(ci1->addr),&port);
3319 ci1->port = port;
3320 ci1->db = client->db->id;
3321 ci1->id = client->id;
3322 return REDISMODULE_OK;
3323}
3324
3325/* This is a helper for moduleFireServerEvent() and other functions:
3326 * It populates the replication info structure with the appropriate
3327 * fields depending on the version provided. If the version is not valid
3328 * then REDISMODULE_ERR is returned. Otherwise the function returns
3329 * REDISMODULE_OK and the structure pointed by 'ri' gets populated. */
3330int modulePopulateReplicationInfoStructure(void *ri, int structver) {
3331 if (structver != 1) return REDISMODULE_ERR;
3332
3333 RedisModuleReplicationInfoV1 *ri1 = ri;
3334 memset(ri1,0,sizeof(*ri1));
3335 ri1->version = structver;
3336 ri1->master = server.masterhost==NULL;
3337 ri1->masterhost = server.masterhost? server.masterhost: "";
3338 ri1->masterport = server.masterport;
3339 ri1->replid1 = server.replid;
3340 ri1->replid2 = server.replid2;
3341 ri1->repl1_offset = server.master_repl_offset;
3342 ri1->repl2_offset = server.second_replid_offset;
3343 return REDISMODULE_OK;
3344}
3345
3346/* Return information about the client with the specified ID (that was
3347 * previously obtained via the RedisModule_GetClientId() API). If the
3348 * client exists, REDISMODULE_OK is returned, otherwise REDISMODULE_ERR
3349 * is returned.
3350 *
3351 * When the client exist and the `ci` pointer is not NULL, but points to
3352 * a structure of type RedisModuleClientInfoV1, previously initialized with
3353 * the correct REDISMODULE_CLIENTINFO_INITIALIZER_V1, the structure is populated
3354 * with the following fields:
3355 *
3356 * uint64_t flags; // REDISMODULE_CLIENTINFO_FLAG_*
3357 * uint64_t id; // Client ID
3358 * char addr[46]; // IPv4 or IPv6 address.
3359 * uint16_t port; // TCP port.
3360 * uint16_t db; // Selected DB.
3361 *
3362 * Note: the client ID is useless in the context of this call, since we
3363 * already know, however the same structure could be used in other
3364 * contexts where we don't know the client ID, yet the same structure
3365 * is returned.
3366 *
3367 * With flags having the following meaning:
3368 *
3369 * REDISMODULE_CLIENTINFO_FLAG_SSL Client using SSL connection.
3370 * REDISMODULE_CLIENTINFO_FLAG_PUBSUB Client in Pub/Sub mode.
3371 * REDISMODULE_CLIENTINFO_FLAG_BLOCKED Client blocked in command.
3372 * REDISMODULE_CLIENTINFO_FLAG_TRACKING Client with keys tracking on.
3373 * REDISMODULE_CLIENTINFO_FLAG_UNIXSOCKET Client using unix domain socket.
3374 * REDISMODULE_CLIENTINFO_FLAG_MULTI Client in MULTI state.
3375 *
3376 * However passing NULL is a way to just check if the client exists in case
3377 * we are not interested in any additional information.
3378 *
3379 * This is the correct usage when we want the client info structure
3380 * returned:
3381 *
3382 * RedisModuleClientInfo ci = REDISMODULE_CLIENTINFO_INITIALIZER;
3383 * int retval = RedisModule_GetClientInfoById(&ci,client_id);
3384 * if (retval == REDISMODULE_OK) {
3385 * printf("Address: %s\n", ci.addr);
3386 * }
3387 */
3388int RM_GetClientInfoById(void *ci, uint64_t id) {
3389 client *client = lookupClientByID(id);
3390 if (client == NULL) return REDISMODULE_ERR;
3391 if (ci == NULL) return REDISMODULE_OK;
3392
3393 /* Fill the info structure if passed. */
3394 uint64_t structver = ((uint64_t*)ci)[0];
3395 return modulePopulateClientInfoStructure(ci,client,structver);
3396}
3397
3398/* Returns the name of the client connection with the given ID.
3399 *
3400 * If the client ID does not exist or if the client has no name associated with
3401 * it, NULL is returned. */
3402RedisModuleString *RM_GetClientNameById(RedisModuleCtx *ctx, uint64_t id) {
3403 client *client = lookupClientByID(id);
3404 if (client == NULL || client->name == NULL) return NULL;
3405 robj *name = client->name;
3406 incrRefCount(name);
3407 autoMemoryAdd(ctx, REDISMODULE_AM_STRING, name);
3408 return name;
3409}
3410
3411/* Sets the name of the client with the given ID. This is equivalent to the client calling
3412 * `CLIENT SETNAME name`.
3413 *
3414 * Returns REDISMODULE_OK on success. On failure, REDISMODULE_ERR is returned
3415 * and errno is set as follows:
3416 *
3417 * - ENOENT if the client does not exist
3418 * - EINVAL if the name contains invalid characters */
3419int RM_SetClientNameById(uint64_t id, RedisModuleString *name) {
3420 client *client = lookupClientByID(id);
3421 if (client == NULL) {
3422 errno = ENOENT;
3423 return REDISMODULE_ERR;
3424 }
3425 if (clientSetName(client, name) == C_ERR) {
3426 errno = EINVAL;
3427 return REDISMODULE_ERR;
3428 }
3429 return REDISMODULE_OK;
3430}
3431
3432/* Publish a message to subscribers (see PUBLISH command). */
3433int RM_PublishMessage(RedisModuleCtx *ctx, RedisModuleString *channel, RedisModuleString *message) {
3434 UNUSED(ctx);
3435 return pubsubPublishMessageAndPropagateToCluster(channel, message, 0);
3436}
3437
3438/* Publish a message to shard-subscribers (see SPUBLISH command). */
3439int RM_PublishMessageShard(RedisModuleCtx *ctx, RedisModuleString *channel, RedisModuleString *message) {
3440 UNUSED(ctx);
3441 return pubsubPublishMessageAndPropagateToCluster(channel, message, 1);
3442}
3443
3444/* Return the currently selected DB. */
3445int RM_GetSelectedDb(RedisModuleCtx *ctx) {
3446 return ctx->client->db->id;
3447}
3448
3449
3450/* Return the current context's flags. The flags provide information on the
3451 * current request context (whether the client is a Lua script or in a MULTI),
3452 * and about the Redis instance in general, i.e replication and persistence.
3453 *
3454 * It is possible to call this function even with a NULL context, however
3455 * in this case the following flags will not be reported:
3456 *
3457 * * LUA, MULTI, REPLICATED, DIRTY (see below for more info).
3458 *
3459 * Available flags and their meaning:
3460 *
3461 * * REDISMODULE_CTX_FLAGS_LUA: The command is running in a Lua script
3462 *
3463 * * REDISMODULE_CTX_FLAGS_MULTI: The command is running inside a transaction
3464 *
3465 * * REDISMODULE_CTX_FLAGS_REPLICATED: The command was sent over the replication
3466 * link by the MASTER
3467 *
3468 * * REDISMODULE_CTX_FLAGS_MASTER: The Redis instance is a master
3469 *
3470 * * REDISMODULE_CTX_FLAGS_SLAVE: The Redis instance is a slave
3471 *
3472 * * REDISMODULE_CTX_FLAGS_READONLY: The Redis instance is read-only
3473 *
3474 * * REDISMODULE_CTX_FLAGS_CLUSTER: The Redis instance is in cluster mode
3475 *
3476 * * REDISMODULE_CTX_FLAGS_AOF: The Redis instance has AOF enabled
3477 *
3478 * * REDISMODULE_CTX_FLAGS_RDB: The instance has RDB enabled
3479 *
3480 * * REDISMODULE_CTX_FLAGS_MAXMEMORY: The instance has Maxmemory set
3481 *
3482 * * REDISMODULE_CTX_FLAGS_EVICT: Maxmemory is set and has an eviction
3483 * policy that may delete keys
3484 *
3485 * * REDISMODULE_CTX_FLAGS_OOM: Redis is out of memory according to the
3486 * maxmemory setting.
3487 *
3488 * * REDISMODULE_CTX_FLAGS_OOM_WARNING: Less than 25% of memory remains before
3489 * reaching the maxmemory level.
3490 *
3491 * * REDISMODULE_CTX_FLAGS_LOADING: Server is loading RDB/AOF
3492 *
3493 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_STALE: No active link with the master.
3494 *
3495 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_CONNECTING: The replica is trying to
3496 * connect with the master.
3497 *
3498 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_TRANSFERRING: Master -> Replica RDB
3499 * transfer is in progress.
3500 *
3501 * * REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE: The replica has an active link
3502 * with its master. This is the
3503 * contrary of STALE state.
3504 *
3505 * * REDISMODULE_CTX_FLAGS_ACTIVE_CHILD: There is currently some background
3506 * process active (RDB, AUX or module).
3507 *
3508 * * REDISMODULE_CTX_FLAGS_MULTI_DIRTY: The next EXEC will fail due to dirty
3509 * CAS (touched keys).
3510 *
3511 * * REDISMODULE_CTX_FLAGS_IS_CHILD: Redis is currently running inside
3512 * background child process.
3513 *
3514 * * REDISMODULE_CTX_FLAGS_RESP3: Indicate the that client attached to this
3515 * context is using RESP3.
3516 */
3517int RM_GetContextFlags(RedisModuleCtx *ctx) {
3518 int flags = 0;
3519
3520 /* Client specific flags */
3521 if (ctx) {
3522 if (ctx->client) {
3523 if (ctx->client->flags & CLIENT_DENY_BLOCKING)
3524 flags |= REDISMODULE_CTX_FLAGS_DENY_BLOCKING;
3525 /* Module command received from MASTER, is replicated. */
3526 if (ctx->client->flags & CLIENT_MASTER)
3527 flags |= REDISMODULE_CTX_FLAGS_REPLICATED;
3528 if (ctx->client->resp == 3) {
3529 flags |= REDISMODULE_CTX_FLAGS_RESP3;
3530 }
3531 }
3532
3533 /* For DIRTY flags, we need the blocked client if used */
3534 client *c = ctx->blocked_client ? ctx->blocked_client->client : ctx->client;
3535 if (c && (c->flags & (CLIENT_DIRTY_CAS|CLIENT_DIRTY_EXEC))) {
3536 flags |= REDISMODULE_CTX_FLAGS_MULTI_DIRTY;
3537 }
3538 }
3539
3540 if (scriptIsRunning())
3541 flags |= REDISMODULE_CTX_FLAGS_LUA;
3542
3543 if (server.in_exec)
3544 flags |= REDISMODULE_CTX_FLAGS_MULTI;
3545
3546 if (server.cluster_enabled)
3547 flags |= REDISMODULE_CTX_FLAGS_CLUSTER;
3548
3549 if (server.async_loading)
3550 flags |= REDISMODULE_CTX_FLAGS_ASYNC_LOADING;
3551 else if (server.loading)
3552 flags |= REDISMODULE_CTX_FLAGS_LOADING;
3553
3554 /* Maxmemory and eviction policy */
3555 if (server.maxmemory > 0 && (!server.masterhost || !server.repl_slave_ignore_maxmemory)) {
3556 flags |= REDISMODULE_CTX_FLAGS_MAXMEMORY;
3557
3558 if (server.maxmemory_policy != MAXMEMORY_NO_EVICTION)
3559 flags |= REDISMODULE_CTX_FLAGS_EVICT;
3560 }
3561
3562 /* Persistence flags */
3563 if (server.aof_state != AOF_OFF)
3564 flags |= REDISMODULE_CTX_FLAGS_AOF;
3565 if (server.saveparamslen > 0)
3566 flags |= REDISMODULE_CTX_FLAGS_RDB;
3567
3568 /* Replication flags */
3569 if (server.masterhost == NULL) {
3570 flags |= REDISMODULE_CTX_FLAGS_MASTER;
3571 } else {
3572 flags |= REDISMODULE_CTX_FLAGS_SLAVE;
3573 if (server.repl_slave_ro)
3574 flags |= REDISMODULE_CTX_FLAGS_READONLY;
3575
3576 /* Replica state flags. */
3577 if (server.repl_state == REPL_STATE_CONNECT ||
3578 server.repl_state == REPL_STATE_CONNECTING)
3579 {
3580 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_CONNECTING;
3581 } else if (server.repl_state == REPL_STATE_TRANSFER) {
3582 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_TRANSFERRING;
3583 } else if (server.repl_state == REPL_STATE_CONNECTED) {
3584 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_ONLINE;
3585 }
3586
3587 if (server.repl_state != REPL_STATE_CONNECTED)
3588 flags |= REDISMODULE_CTX_FLAGS_REPLICA_IS_STALE;
3589 }
3590
3591 /* OOM flag. */
3592 float level;
3593 int retval = getMaxmemoryState(NULL,NULL,NULL,&level);
3594 if (retval == C_ERR) flags |= REDISMODULE_CTX_FLAGS_OOM;
3595 if (level > 0.75) flags |= REDISMODULE_CTX_FLAGS_OOM_WARNING;
3596
3597 /* Presence of children processes. */
3598 if (hasActiveChildProcess()) flags |= REDISMODULE_CTX_FLAGS_ACTIVE_CHILD;
3599 if (server.in_fork_child) flags |= REDISMODULE_CTX_FLAGS_IS_CHILD;
3600
3601 return flags;
3602}
3603
3604/* Returns true if a client sent the CLIENT PAUSE command to the server or
3605 * if Redis Cluster does a manual failover, pausing the clients.
3606 * This is needed when we have a master with replicas, and want to write,
3607 * without adding further data to the replication channel, that the replicas
3608 * replication offset, match the one of the master. When this happens, it is
3609 * safe to failover the master without data loss.
3610 *
3611 * However modules may generate traffic by calling RedisModule_Call() with
3612 * the "!" flag, or by calling RedisModule_Replicate(), in a context outside
3613 * commands execution, for instance in timeout callbacks, threads safe
3614 * contexts, and so forth. When modules will generate too much traffic, it
3615 * will be hard for the master and replicas offset to match, because there
3616 * is more data to send in the replication channel.
3617 *
3618 * So modules may want to try to avoid very heavy background work that has
3619 * the effect of creating data to the replication channel, when this function
3620 * returns true. This is mostly useful for modules that have background
3621 * garbage collection tasks, or that do writes and replicate such writes
3622 * periodically in timer callbacks or other periodic callbacks.
3623 */
3624int RM_AvoidReplicaTraffic() {
3625 return checkClientPauseTimeoutAndReturnIfPaused();
3626}
3627
3628/* Change the currently selected DB. Returns an error if the id
3629 * is out of range.
3630 *
3631 * Note that the client will retain the currently selected DB even after
3632 * the Redis command implemented by the module calling this function
3633 * returns.
3634 *
3635 * If the module command wishes to change something in a different DB and
3636 * returns back to the original one, it should call RedisModule_GetSelectedDb()
3637 * before in order to restore the old DB number before returning. */
3638int RM_SelectDb(RedisModuleCtx *ctx, int newid) {
3639 int retval = selectDb(ctx->client,newid);
3640 return (retval == C_OK) ? REDISMODULE_OK : REDISMODULE_ERR;
3641}
3642
3643/* Check if a key exists, without affecting its last access time.
3644 *
3645 * This is equivalent to calling RM_OpenKey with the mode REDISMODULE_READ |
3646 * REDISMODULE_OPEN_KEY_NOTOUCH, then checking if NULL was returned and, if not,
3647 * calling RM_CloseKey on the opened key.
3648 */
3649int RM_KeyExists(RedisModuleCtx *ctx, robj *keyname) {
3650 robj *value = lookupKeyReadWithFlags(ctx->client->db, keyname, LOOKUP_NOTOUCH);
3651 return (value != NULL);
3652}
3653
3654/* Initialize a RedisModuleKey struct */
3655static void moduleInitKey(RedisModuleKey *kp, RedisModuleCtx *ctx, robj *keyname, robj *value, int mode){
3656 kp->ctx = ctx;
3657 kp->db = ctx->client->db;
3658 kp->key = keyname;
3659 incrRefCount(keyname);
3660 kp->value = value;
3661 kp->iter = NULL;
3662 kp->mode = mode;
3663 if (kp->value) moduleInitKeyTypeSpecific(kp);
3664}
3665
3666/* Initialize the type-specific part of the key. Only when key has a value. */
3667static void moduleInitKeyTypeSpecific(RedisModuleKey *key) {
3668 switch (key->value->type) {
3669 case OBJ_ZSET: zsetKeyReset(key); break;
3670 case OBJ_STREAM: key->u.stream.signalready = 0; break;
3671 }
3672}
3673
3674/* Return a handle representing a Redis key, so that it is possible
3675 * to call other APIs with the key handle as argument to perform
3676 * operations on the key.
3677 *
3678 * The return value is the handle representing the key, that must be
3679 * closed with RM_CloseKey().
3680 *
3681 * If the key does not exist and WRITE mode is requested, the handle
3682 * is still returned, since it is possible to perform operations on
3683 * a yet not existing key (that will be created, for example, after
3684 * a list push operation). If the mode is just READ instead, and the
3685 * key does not exist, NULL is returned. However it is still safe to
3686 * call RedisModule_CloseKey() and RedisModule_KeyType() on a NULL
3687 * value. */
3688RedisModuleKey *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
3689 RedisModuleKey *kp;
3690 robj *value;
3691 int flags = mode & REDISMODULE_OPEN_KEY_NOTOUCH? LOOKUP_NOTOUCH: 0;
3692
3693 if (mode & REDISMODULE_WRITE) {
3694 value = lookupKeyWriteWithFlags(ctx->client->db,keyname, flags);
3695 } else {
3696 value = lookupKeyReadWithFlags(ctx->client->db,keyname, flags);
3697 if (value == NULL) {
3698 return NULL;
3699 }
3700 }
3701
3702 /* Setup the key handle. */
3703 kp = zmalloc(sizeof(*kp));
3704 moduleInitKey(kp, ctx, keyname, value, mode);
3705 autoMemoryAdd(ctx,REDISMODULE_AM_KEY,kp);
3706 return kp;
3707}
3708
3709/* Destroy a RedisModuleKey struct (freeing is the responsibility of the caller). */
3710static void moduleCloseKey(RedisModuleKey *key) {
3711 int signal = SHOULD_SIGNAL_MODIFIED_KEYS(key->ctx);
3712 if ((key->mode & REDISMODULE_WRITE) && signal)
3713 signalModifiedKey(key->ctx->client,key->db,key->key);
3714 if (key->value) {
3715 if (key->iter) moduleFreeKeyIterator(key);
3716 switch (key->value->type) {
3717 case OBJ_ZSET:
3718 RM_ZsetRangeStop(key);
3719 break;
3720 case OBJ_STREAM:
3721 if (key->u.stream.signalready)
3722 /* One or more RM_StreamAdd() have been done. */
3723 signalKeyAsReady(key->db, key->key, OBJ_STREAM);
3724 break;
3725 }
3726 }
3727 serverAssert(key->iter == NULL);
3728 decrRefCount(key->key);
3729}
3730
3731/* Close a key handle. */
3732void RM_CloseKey(RedisModuleKey *key) {
3733 if (key == NULL) return;
3734 moduleCloseKey(key);
3735 autoMemoryFreed(key->ctx,REDISMODULE_AM_KEY,key);
3736 zfree(key);
3737}
3738
3739/* Return the type of the key. If the key pointer is NULL then
3740 * REDISMODULE_KEYTYPE_EMPTY is returned. */
3741int RM_KeyType(RedisModuleKey *key) {
3742 if (key == NULL || key->value == NULL) return REDISMODULE_KEYTYPE_EMPTY;
3743 /* We map between defines so that we are free to change the internal
3744 * defines as desired. */
3745 switch(key->value->type) {
3746 case OBJ_STRING: return REDISMODULE_KEYTYPE_STRING;
3747 case OBJ_LIST: return REDISMODULE_KEYTYPE_LIST;
3748 case OBJ_SET: return REDISMODULE_KEYTYPE_SET;
3749 case OBJ_ZSET: return REDISMODULE_KEYTYPE_ZSET;
3750 case OBJ_HASH: return REDISMODULE_KEYTYPE_HASH;
3751 case OBJ_MODULE: return REDISMODULE_KEYTYPE_MODULE;
3752 case OBJ_STREAM: return REDISMODULE_KEYTYPE_STREAM;
3753 default: return REDISMODULE_KEYTYPE_EMPTY;
3754 }
3755}
3756
3757/* Return the length of the value associated with the key.
3758 * For strings this is the length of the string. For all the other types
3759 * is the number of elements (just counting keys for hashes).
3760 *
3761 * If the key pointer is NULL or the key is empty, zero is returned. */
3762size_t RM_ValueLength(RedisModuleKey *key) {
3763 if (key == NULL || key->value == NULL) return 0;
3764 switch(key->value->type) {
3765 case OBJ_STRING: return stringObjectLen(key->value);
3766 case OBJ_LIST: return listTypeLength(key->value);
3767 case OBJ_SET: return setTypeSize(key->value);
3768 case OBJ_ZSET: return zsetLength(key->value);
3769 case OBJ_HASH: return hashTypeLength(key->value);
3770 case OBJ_STREAM: return streamLength(key->value);
3771 default: return 0;
3772 }
3773}
3774
3775/* If the key is open for writing, remove it, and setup the key to
3776 * accept new writes as an empty key (that will be created on demand).
3777 * On success REDISMODULE_OK is returned. If the key is not open for
3778 * writing REDISMODULE_ERR is returned. */
3779int RM_DeleteKey(RedisModuleKey *key) {
3780 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
3781 if (key->value) {
3782 dbDelete(key->db,key->key);
3783 key->value = NULL;
3784 }
3785 return REDISMODULE_OK;
3786}
3787
3788/* If the key is open for writing, unlink it (that is delete it in a
3789 * non-blocking way, not reclaiming memory immediately) and setup the key to
3790 * accept new writes as an empty key (that will be created on demand).
3791 * On success REDISMODULE_OK is returned. If the key is not open for
3792 * writing REDISMODULE_ERR is returned. */
3793int RM_UnlinkKey(RedisModuleKey *key) {
3794 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
3795 if (key->value) {
3796 dbAsyncDelete(key->db,key->key);
3797 key->value = NULL;
3798 }
3799 return REDISMODULE_OK;
3800}
3801
3802/* Return the key expire value, as milliseconds of remaining TTL.
3803 * If no TTL is associated with the key or if the key is empty,
3804 * REDISMODULE_NO_EXPIRE is returned. */
3805mstime_t RM_GetExpire(RedisModuleKey *key) {
3806 mstime_t expire = getExpire(key->db,key->key);
3807 if (expire == -1 || key->value == NULL)
3808 return REDISMODULE_NO_EXPIRE;
3809 expire -= mstime();
3810 return expire >= 0 ? expire : 0;
3811}
3812
3813/* Set a new expire for the key. If the special expire
3814 * REDISMODULE_NO_EXPIRE is set, the expire is cancelled if there was
3815 * one (the same as the PERSIST command).
3816 *
3817 * Note that the expire must be provided as a positive integer representing
3818 * the number of milliseconds of TTL the key should have.
3819 *
3820 * The function returns REDISMODULE_OK on success or REDISMODULE_ERR if
3821 * the key was not open for writing or is an empty key. */
3822int RM_SetExpire(RedisModuleKey *key, mstime_t expire) {
3823 if (!(key->mode & REDISMODULE_WRITE) || key->value == NULL || (expire < 0 && expire != REDISMODULE_NO_EXPIRE))
3824 return REDISMODULE_ERR;
3825 if (expire != REDISMODULE_NO_EXPIRE) {
3826 expire += mstime();
3827 setExpire(key->ctx->client,key->db,key->key,expire);
3828 } else {
3829 removeExpire(key->db,key->key);
3830 }
3831 return REDISMODULE_OK;
3832}
3833
3834/* Return the key expire value, as absolute Unix timestamp.
3835 * If no TTL is associated with the key or if the key is empty,
3836 * REDISMODULE_NO_EXPIRE is returned. */
3837mstime_t RM_GetAbsExpire(RedisModuleKey *key) {
3838 mstime_t expire = getExpire(key->db,key->key);
3839 if (expire == -1 || key->value == NULL)
3840 return REDISMODULE_NO_EXPIRE;
3841 return expire;
3842}
3843
3844/* Set a new expire for the key. If the special expire
3845 * REDISMODULE_NO_EXPIRE is set, the expire is cancelled if there was
3846 * one (the same as the PERSIST command).
3847 *
3848 * Note that the expire must be provided as a positive integer representing
3849 * the absolute Unix timestamp the key should have.
3850 *
3851 * The function returns REDISMODULE_OK on success or REDISMODULE_ERR if
3852 * the key was not open for writing or is an empty key. */
3853int RM_SetAbsExpire(RedisModuleKey *key, mstime_t expire) {
3854 if (!(key->mode & REDISMODULE_WRITE) || key->value == NULL || (expire < 0 && expire != REDISMODULE_NO_EXPIRE))
3855 return REDISMODULE_ERR;
3856 if (expire != REDISMODULE_NO_EXPIRE) {
3857 setExpire(key->ctx->client,key->db,key->key,expire);
3858 } else {
3859 removeExpire(key->db,key->key);
3860 }
3861 return REDISMODULE_OK;
3862}
3863
3864/* Performs similar operation to FLUSHALL, and optionally start a new AOF file (if enabled)
3865 * If restart_aof is true, you must make sure the command that triggered this call is not
3866 * propagated to the AOF file.
3867 * When async is set to true, db contents will be freed by a background thread. */
3868void RM_ResetDataset(int restart_aof, int async) {
3869 if (restart_aof && server.aof_state != AOF_OFF) stopAppendOnly();
3870 flushAllDataAndResetRDB(async? EMPTYDB_ASYNC: EMPTYDB_NO_FLAGS);
3871 if (server.aof_enabled && restart_aof) restartAOFAfterSYNC();
3872}
3873
3874/* Returns the number of keys in the current db. */
3875unsigned long long RM_DbSize(RedisModuleCtx *ctx) {
3876 return dictSize(ctx->client->db->dict);
3877}
3878
3879/* Returns a name of a random key, or NULL if current db is empty. */
3880RedisModuleString *RM_RandomKey(RedisModuleCtx *ctx) {
3881 robj *key = dbRandomKey(ctx->client->db);
3882 autoMemoryAdd(ctx,REDISMODULE_AM_STRING,key);
3883 return key;
3884}
3885
3886/* Returns the name of the key currently being processed. */
3887const RedisModuleString *RM_GetKeyNameFromOptCtx(RedisModuleKeyOptCtx *ctx) {
3888 return ctx->from_key;
3889}
3890
3891/* Returns the name of the target key currently being processed. */
3892const RedisModuleString *RM_GetToKeyNameFromOptCtx(RedisModuleKeyOptCtx *ctx) {
3893 return ctx->to_key;
3894}
3895
3896/* Returns the dbid currently being processed. */
3897int RM_GetDbIdFromOptCtx(RedisModuleKeyOptCtx *ctx) {
3898 return ctx->from_dbid;
3899}
3900
3901/* Returns the target dbid currently being processed. */
3902int RM_GetToDbIdFromOptCtx(RedisModuleKeyOptCtx *ctx) {
3903 return ctx->to_dbid;
3904}
3905/* --------------------------------------------------------------------------
3906 * ## Key API for String type
3907 *
3908 * See also RM_ValueLength(), which returns the length of a string.
3909 * -------------------------------------------------------------------------- */
3910
3911/* If the key is open for writing, set the specified string 'str' as the
3912 * value of the key, deleting the old value if any.
3913 * On success REDISMODULE_OK is returned. If the key is not open for
3914 * writing or there is an active iterator, REDISMODULE_ERR is returned. */
3915int RM_StringSet(RedisModuleKey *key, RedisModuleString *str) {
3916 if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR;
3917 RM_DeleteKey(key);
3918 setKey(key->ctx->client,key->db,key->key,str,SETKEY_NO_SIGNAL);
3919 key->value = str;
3920 return REDISMODULE_OK;
3921}
3922
3923/* Prepare the key associated string value for DMA access, and returns
3924 * a pointer and size (by reference), that the user can use to read or
3925 * modify the string in-place accessing it directly via pointer.
3926 *
3927 * The 'mode' is composed by bitwise OR-ing the following flags:
3928 *
3929 * REDISMODULE_READ -- Read access
3930 * REDISMODULE_WRITE -- Write access
3931 *
3932 * If the DMA is not requested for writing, the pointer returned should
3933 * only be accessed in a read-only fashion.
3934 *
3935 * On error (wrong type) NULL is returned.
3936 *
3937 * DMA access rules:
3938 *
3939 * 1. No other key writing function should be called since the moment
3940 * the pointer is obtained, for all the time we want to use DMA access
3941 * to read or modify the string.
3942 *
3943 * 2. Each time RM_StringTruncate() is called, to continue with the DMA
3944 * access, RM_StringDMA() should be called again to re-obtain
3945 * a new pointer and length.
3946 *
3947 * 3. If the returned pointer is not NULL, but the length is zero, no
3948 * byte can be touched (the string is empty, or the key itself is empty)
3949 * so a RM_StringTruncate() call should be used if there is to enlarge
3950 * the string, and later call StringDMA() again to get the pointer.
3951 */
3952char *RM_StringDMA(RedisModuleKey *key, size_t *len, int mode) {
3953 /* We need to return *some* pointer for empty keys, we just return
3954 * a string literal pointer, that is the advantage to be mapped into
3955 * a read only memory page, so the module will segfault if a write
3956 * attempt is performed. */
3957 char *emptystring = "<dma-empty-string>";
3958 if (key->value == NULL) {
3959 *len = 0;
3960 return emptystring;
3961 }
3962
3963 if (key->value->type != OBJ_STRING) return NULL;
3964
3965 /* For write access, and even for read access if the object is encoded,
3966 * we unshare the string (that has the side effect of decoding it). */
3967 if ((mode & REDISMODULE_WRITE) || key->value->encoding != OBJ_ENCODING_RAW)
3968 key->value = dbUnshareStringValue(key->db, key->key, key->value);
3969
3970 *len = sdslen(key->value->ptr);
3971 return key->value->ptr;
3972}
3973
3974/* If the key is open for writing and is of string type, resize it, padding
3975 * with zero bytes if the new length is greater than the old one.
3976 *
3977 * After this call, RM_StringDMA() must be called again to continue
3978 * DMA access with the new pointer.
3979 *
3980 * The function returns REDISMODULE_OK on success, and REDISMODULE_ERR on
3981 * error, that is, the key is not open for writing, is not a string
3982 * or resizing for more than 512 MB is requested.
3983 *
3984 * If the key is empty, a string key is created with the new string value
3985 * unless the new length value requested is zero. */
3986int RM_StringTruncate(RedisModuleKey *key, size_t newlen) {
3987 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
3988 if (key->value && key->value->type != OBJ_STRING) return REDISMODULE_ERR;
3989 if (newlen > 512*1024*1024) return REDISMODULE_ERR;
3990
3991 /* Empty key and new len set to 0. Just return REDISMODULE_OK without
3992 * doing anything. */
3993 if (key->value == NULL && newlen == 0) return REDISMODULE_OK;
3994
3995 if (key->value == NULL) {
3996 /* Empty key: create it with the new size. */
3997 robj *o = createObject(OBJ_STRING,sdsnewlen(NULL, newlen));
3998 setKey(key->ctx->client,key->db,key->key,o,SETKEY_NO_SIGNAL);
3999 key->value = o;
4000 decrRefCount(o);
4001 } else {
4002 /* Unshare and resize. */
4003 key->value = dbUnshareStringValue(key->db, key->key, key->value);
4004 size_t curlen = sdslen(key->value->ptr);
4005 if (newlen > curlen) {
4006 key->value->ptr = sdsgrowzero(key->value->ptr,newlen);
4007 } else if (newlen < curlen) {
4008 sdssubstr(key->value->ptr,0,newlen);
4009 /* If the string is too wasteful, reallocate it. */
4010 if (sdslen(key->value->ptr) < sdsavail(key->value->ptr))
4011 key->value->ptr = sdsRemoveFreeSpace(key->value->ptr);
4012 }
4013 }
4014 return REDISMODULE_OK;
4015}
4016
4017/* --------------------------------------------------------------------------
4018 * ## Key API for List type
4019 *
4020 * Many of the list functions access elements by index. Since a list is in
4021 * essence a doubly-linked list, accessing elements by index is generally an
4022 * O(N) operation. However, if elements are accessed sequentially or with
4023 * indices close together, the functions are optimized to seek the index from
4024 * the previous index, rather than seeking from the ends of the list.
4025 *
4026 * This enables iteration to be done efficiently using a simple for loop:
4027 *
4028 * long n = RM_ValueLength(key);
4029 * for (long i = 0; i < n; i++) {
4030 * RedisModuleString *elem = RedisModule_ListGet(key, i);
4031 * // Do stuff...
4032 * }
4033 *
4034 * Note that after modifying a list using RM_ListPop, RM_ListSet or
4035 * RM_ListInsert, the internal iterator is invalidated so the next operation
4036 * will require a linear seek.
4037 *
4038 * Modifying a list in any another way, for example using RM_Call(), while a key
4039 * is open will confuse the internal iterator and may cause trouble if the key
4040 * is used after such modifications. The key must be reopened in this case.
4041 *
4042 * See also RM_ValueLength(), which returns the length of a list.
4043 * -------------------------------------------------------------------------- */
4044
4045/* Seeks the key's internal list iterator to the given index. On success, 1 is
4046 * returned and key->iter, key->u.list.entry and key->u.list.index are set. On
4047 * failure, 0 is returned and errno is set as required by the list API
4048 * functions. */
4049int moduleListIteratorSeek(RedisModuleKey *key, long index, int mode) {
4050 if (!key) {
4051 errno = EINVAL;
4052 return 0;
4053 } else if (!key->value || key->value->type != OBJ_LIST) {
4054 errno = ENOTSUP;
4055 return 0;
4056 } if (!(key->mode & mode)) {
4057 errno = EBADF;
4058 return 0;
4059 }
4060
4061 long length = listTypeLength(key->value);
4062 if (index < -length || index >= length) {
4063 errno = EDOM; /* Invalid index */
4064 return 0;
4065 }
4066
4067 if (key->iter == NULL) {
4068 /* No existing iterator. Create one. */
4069 key->iter = listTypeInitIterator(key->value, index, LIST_TAIL);
4070 serverAssert(key->iter != NULL);
4071 serverAssert(listTypeNext(key->iter, &key->u.list.entry));
4072 key->u.list.index = index;
4073 return 1;
4074 }
4075
4076 /* There's an existing iterator. Make sure the requested index has the same
4077 * sign as the iterator's index. */
4078 if (index < 0 && key->u.list.index >= 0) index += length;
4079 else if (index >= 0 && key->u.list.index < 0) index -= length;
4080
4081 if (index == key->u.list.index) return 1; /* We're done. */
4082
4083 /* Seek the iterator to the requested index. */
4084 unsigned char dir = key->u.list.index < index ? LIST_TAIL : LIST_HEAD;
4085 listTypeSetIteratorDirection(key->iter, dir);
4086 while (key->u.list.index != index) {
4087 serverAssert(listTypeNext(key->iter, &key->u.list.entry));
4088 key->u.list.index += dir == LIST_HEAD ? -1 : 1;
4089 }
4090 return 1;
4091}
4092
4093/* Push an element into a list, on head or tail depending on 'where' argument
4094 * (REDISMODULE_LIST_HEAD or REDISMODULE_LIST_TAIL). If the key refers to an
4095 * empty key opened for writing, the key is created. On success, REDISMODULE_OK
4096 * is returned. On failure, REDISMODULE_ERR is returned and `errno` is set as
4097 * follows:
4098 *
4099 * - EINVAL if key or ele is NULL.
4100 * - ENOTSUP if the key is of another type than list.
4101 * - EBADF if the key is not opened for writing.
4102 *
4103 * Note: Before Redis 7.0, `errno` was not set by this function. */
4104int RM_ListPush(RedisModuleKey *key, int where, RedisModuleString *ele) {
4105 if (!key || !ele) {
4106 errno = EINVAL;
4107 return REDISMODULE_ERR;
4108 } else if (key->value != NULL && key->value->type != OBJ_LIST) {
4109 errno = ENOTSUP;
4110 return REDISMODULE_ERR;
4111 } if (!(key->mode & REDISMODULE_WRITE)) {
4112 errno = EBADF;
4113 return REDISMODULE_ERR;
4114 }
4115
4116 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
4117 if (key->value && key->value->type != OBJ_LIST) return REDISMODULE_ERR;
4118 if (key->iter) {
4119 listTypeReleaseIterator(key->iter);
4120 key->iter = NULL;
4121 }
4122 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_LIST);
4123 listTypePush(key->value, ele,
4124 (where == REDISMODULE_LIST_HEAD) ? LIST_HEAD : LIST_TAIL);
4125 return REDISMODULE_OK;
4126}
4127
4128/* Pop an element from the list, and returns it as a module string object
4129 * that the user should be free with RM_FreeString() or by enabling
4130 * automatic memory. The `where` argument specifies if the element should be
4131 * popped from the beginning or the end of the list (REDISMODULE_LIST_HEAD or
4132 * REDISMODULE_LIST_TAIL). On failure, the command returns NULL and sets
4133 * `errno` as follows:
4134 *
4135 * - EINVAL if key is NULL.
4136 * - ENOTSUP if the key is empty or of another type than list.
4137 * - EBADF if the key is not opened for writing.
4138 *
4139 * Note: Before Redis 7.0, `errno` was not set by this function. */
4140RedisModuleString *RM_ListPop(RedisModuleKey *key, int where) {
4141 if (!key) {
4142 errno = EINVAL;
4143 return NULL;
4144 } else if (key->value == NULL || key->value->type != OBJ_LIST) {
4145 errno = ENOTSUP;
4146 return NULL;
4147 } else if (!(key->mode & REDISMODULE_WRITE)) {
4148 errno = EBADF;
4149 return NULL;
4150 }
4151 if (key->iter) {
4152 listTypeReleaseIterator(key->iter);
4153 key->iter = NULL;
4154 }
4155 robj *ele = listTypePop(key->value,
4156 (where == REDISMODULE_LIST_HEAD) ? LIST_HEAD : LIST_TAIL);
4157 robj *decoded = getDecodedObject(ele);
4158 decrRefCount(ele);
4159 moduleDelKeyIfEmpty(key);
4160 autoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,decoded);
4161 return decoded;
4162}
4163
4164/* Returns the element at index `index` in the list stored at `key`, like the
4165 * LINDEX command. The element should be free'd using RM_FreeString() or using
4166 * automatic memory management.
4167 *
4168 * The index is zero-based, so 0 means the first element, 1 the second element
4169 * and so on. Negative indices can be used to designate elements starting at the
4170 * tail of the list. Here, -1 means the last element, -2 means the penultimate
4171 * and so forth.
4172 *
4173 * When no value is found at the given key and index, NULL is returned and
4174 * `errno` is set as follows:
4175 *
4176 * - EINVAL if key is NULL.
4177 * - ENOTSUP if the key is not a list.
4178 * - EBADF if the key is not opened for reading.
4179 * - EDOM if the index is not a valid index in the list.
4180 */
4181RedisModuleString *RM_ListGet(RedisModuleKey *key, long index) {
4182 if (moduleListIteratorSeek(key, index, REDISMODULE_READ)) {
4183 robj *elem = listTypeGet(&key->u.list.entry);
4184 robj *decoded = getDecodedObject(elem);
4185 decrRefCount(elem);
4186 autoMemoryAdd(key->ctx, REDISMODULE_AM_STRING, decoded);
4187 return decoded;
4188 } else {
4189 return NULL;
4190 }
4191}
4192
4193/* Replaces the element at index `index` in the list stored at `key`.
4194 *
4195 * The index is zero-based, so 0 means the first element, 1 the second element
4196 * and so on. Negative indices can be used to designate elements starting at the
4197 * tail of the list. Here, -1 means the last element, -2 means the penultimate
4198 * and so forth.
4199 *
4200 * On success, REDISMODULE_OK is returned. On failure, REDISMODULE_ERR is
4201 * returned and `errno` is set as follows:
4202 *
4203 * - EINVAL if key or value is NULL.
4204 * - ENOTSUP if the key is not a list.
4205 * - EBADF if the key is not opened for writing.
4206 * - EDOM if the index is not a valid index in the list.
4207 */
4208int RM_ListSet(RedisModuleKey *key, long index, RedisModuleString *value) {
4209 if (!value) {
4210 errno = EINVAL;
4211 return REDISMODULE_ERR;
4212 }
4213 if (moduleListIteratorSeek(key, index, REDISMODULE_WRITE)) {
4214 listTypeReplace(&key->u.list.entry, value);
4215 /* A note in quicklist.c forbids use of iterator after insert, so
4216 * probably also after replace. */
4217 listTypeReleaseIterator(key->iter);
4218 key->iter = NULL;
4219 return REDISMODULE_OK;
4220 } else {
4221 return REDISMODULE_ERR;
4222 }
4223}
4224
4225/* Inserts an element at the given index.
4226 *
4227 * The index is zero-based, so 0 means the first element, 1 the second element
4228 * and so on. Negative indices can be used to designate elements starting at the
4229 * tail of the list. Here, -1 means the last element, -2 means the penultimate
4230 * and so forth. The index is the element's index after inserting it.
4231 *
4232 * On success, REDISMODULE_OK is returned. On failure, REDISMODULE_ERR is
4233 * returned and `errno` is set as follows:
4234 *
4235 * - EINVAL if key or value is NULL.
4236 * - ENOTSUP if the key of another type than list.
4237 * - EBADF if the key is not opened for writing.
4238 * - EDOM if the index is not a valid index in the list.
4239 */
4240int RM_ListInsert(RedisModuleKey *key, long index, RedisModuleString *value) {
4241 if (!value) {
4242 errno = EINVAL;
4243 return REDISMODULE_ERR;
4244 } else if (key != NULL && key->value == NULL &&
4245 (index == 0 || index == -1)) {
4246 /* Insert in empty key => push. */
4247 return RM_ListPush(key, REDISMODULE_LIST_TAIL, value);
4248 } else if (key != NULL && key->value != NULL &&
4249 key->value->type == OBJ_LIST &&
4250 (index == (long)listTypeLength(key->value) || index == -1)) {
4251 /* Insert after the last element => push tail. */
4252 return RM_ListPush(key, REDISMODULE_LIST_TAIL, value);
4253 } else if (key != NULL && key->value != NULL &&
4254 key->value->type == OBJ_LIST &&
4255 (index == 0 || index == -(long)listTypeLength(key->value) - 1)) {
4256 /* Insert before the first element => push head. */
4257 return RM_ListPush(key, REDISMODULE_LIST_HEAD, value);
4258 }
4259 if (moduleListIteratorSeek(key, index, REDISMODULE_WRITE)) {
4260 int where = index < 0 ? LIST_TAIL : LIST_HEAD;
4261 listTypeInsert(&key->u.list.entry, value, where);
4262 /* A note in quicklist.c forbids use of iterator after insert. */
4263 listTypeReleaseIterator(key->iter);
4264 key->iter = NULL;
4265 return REDISMODULE_OK;
4266 } else {
4267 return REDISMODULE_ERR;
4268 }
4269}
4270
4271/* Removes an element at the given index. The index is 0-based. A negative index
4272 * can also be used, counting from the end of the list.
4273 *
4274 * On success, REDISMODULE_OK is returned. On failure, REDISMODULE_ERR is
4275 * returned and `errno` is set as follows:
4276 *
4277 * - EINVAL if key or value is NULL.
4278 * - ENOTSUP if the key is not a list.
4279 * - EBADF if the key is not opened for writing.
4280 * - EDOM if the index is not a valid index in the list.
4281 */
4282int RM_ListDelete(RedisModuleKey *key, long index) {
4283 if (moduleListIteratorSeek(key, index, REDISMODULE_WRITE)) {
4284 listTypeDelete(key->iter, &key->u.list.entry);
4285 moduleDelKeyIfEmpty(key);
4286 return REDISMODULE_OK;
4287 } else {
4288 return REDISMODULE_ERR;
4289 }
4290}
4291
4292/* --------------------------------------------------------------------------
4293 * ## Key API for Sorted Set type
4294 *
4295 * See also RM_ValueLength(), which returns the length of a sorted set.
4296 * -------------------------------------------------------------------------- */
4297
4298/* Conversion from/to public flags of the Modules API and our private flags,
4299 * so that we have everything decoupled. */
4300int moduleZsetAddFlagsToCoreFlags(int flags) {
4301 int retflags = 0;
4302 if (flags & REDISMODULE_ZADD_XX) retflags |= ZADD_IN_XX;
4303 if (flags & REDISMODULE_ZADD_NX) retflags |= ZADD_IN_NX;
4304 if (flags & REDISMODULE_ZADD_GT) retflags |= ZADD_IN_GT;
4305 if (flags & REDISMODULE_ZADD_LT) retflags |= ZADD_IN_LT;
4306 return retflags;
4307}
4308
4309/* See previous function comment. */
4310int moduleZsetAddFlagsFromCoreFlags(int flags) {
4311 int retflags = 0;
4312 if (flags & ZADD_OUT_ADDED) retflags |= REDISMODULE_ZADD_ADDED;
4313 if (flags & ZADD_OUT_UPDATED) retflags |= REDISMODULE_ZADD_UPDATED;
4314 if (flags & ZADD_OUT_NOP) retflags |= REDISMODULE_ZADD_NOP;
4315 return retflags;
4316}
4317
4318/* Add a new element into a sorted set, with the specified 'score'.
4319 * If the element already exists, the score is updated.
4320 *
4321 * A new sorted set is created at value if the key is an empty open key
4322 * setup for writing.
4323 *
4324 * Additional flags can be passed to the function via a pointer, the flags
4325 * are both used to receive input and to communicate state when the function
4326 * returns. 'flagsptr' can be NULL if no special flags are used.
4327 *
4328 * The input flags are:
4329 *
4330 * REDISMODULE_ZADD_XX: Element must already exist. Do nothing otherwise.
4331 * REDISMODULE_ZADD_NX: Element must not exist. Do nothing otherwise.
4332 * REDISMODULE_ZADD_GT: If element exists, new score must be greater than the current score.
4333 * Do nothing otherwise. Can optionally be combined with XX.
4334 * REDISMODULE_ZADD_LT: If element exists, new score must be less than the current score.
4335 * Do nothing otherwise. Can optionally be combined with XX.
4336 *
4337 * The output flags are:
4338 *
4339 * REDISMODULE_ZADD_ADDED: The new element was added to the sorted set.
4340 * REDISMODULE_ZADD_UPDATED: The score of the element was updated.
4341 * REDISMODULE_ZADD_NOP: No operation was performed because XX or NX flags.
4342 *
4343 * On success the function returns REDISMODULE_OK. On the following errors
4344 * REDISMODULE_ERR is returned:
4345 *
4346 * * The key was not opened for writing.
4347 * * The key is of the wrong type.
4348 * * 'score' double value is not a number (NaN).
4349 */
4350int RM_ZsetAdd(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr) {
4351 int in_flags = 0, out_flags = 0;
4352 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
4353 if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
4354 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET);
4355 if (flagsptr) in_flags = moduleZsetAddFlagsToCoreFlags(*flagsptr);
4356 if (zsetAdd(key->value,score,ele->ptr,in_flags,&out_flags,NULL) == 0) {
4357 if (flagsptr) *flagsptr = 0;
4358 return REDISMODULE_ERR;
4359 }
4360 if (flagsptr) *flagsptr = moduleZsetAddFlagsFromCoreFlags(out_flags);
4361 return REDISMODULE_OK;
4362}
4363
4364/* This function works exactly like RM_ZsetAdd(), but instead of setting
4365 * a new score, the score of the existing element is incremented, or if the
4366 * element does not already exist, it is added assuming the old score was
4367 * zero.
4368 *
4369 * The input and output flags, and the return value, have the same exact
4370 * meaning, with the only difference that this function will return
4371 * REDISMODULE_ERR even when 'score' is a valid double number, but adding it
4372 * to the existing score results into a NaN (not a number) condition.
4373 *
4374 * This function has an additional field 'newscore', if not NULL is filled
4375 * with the new score of the element after the increment, if no error
4376 * is returned. */
4377int RM_ZsetIncrby(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr, double *newscore) {
4378 int in_flags = 0, out_flags = 0;
4379 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
4380 if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
4381 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET);
4382 if (flagsptr) in_flags = moduleZsetAddFlagsToCoreFlags(*flagsptr);
4383 in_flags |= ZADD_IN_INCR;
4384 if (zsetAdd(key->value,score,ele->ptr,in_flags,&out_flags,newscore) == 0) {
4385 if (flagsptr) *flagsptr = 0;
4386 return REDISMODULE_ERR;
4387 }
4388 if (flagsptr) *flagsptr = moduleZsetAddFlagsFromCoreFlags(out_flags);
4389 return REDISMODULE_OK;
4390}
4391
4392/* Remove the specified element from the sorted set.
4393 * The function returns REDISMODULE_OK on success, and REDISMODULE_ERR
4394 * on one of the following conditions:
4395 *
4396 * * The key was not opened for writing.
4397 * * The key is of the wrong type.
4398 *
4399 * The return value does NOT indicate the fact the element was really
4400 * removed (since it existed) or not, just if the function was executed
4401 * with success.
4402 *
4403 * In order to know if the element was removed, the additional argument
4404 * 'deleted' must be passed, that populates the integer by reference
4405 * setting it to 1 or 0 depending on the outcome of the operation.
4406 * The 'deleted' argument can be NULL if the caller is not interested
4407 * to know if the element was really removed.
4408 *
4409 * Empty keys will be handled correctly by doing nothing. */
4410int RM_ZsetRem(RedisModuleKey *key, RedisModuleString *ele, int *deleted) {
4411 if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR;
4412 if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
4413 if (key->value != NULL && zsetDel(key->value,ele->ptr)) {
4414 if (deleted) *deleted = 1;
4415 moduleDelKeyIfEmpty(key);
4416 } else {
4417 if (deleted) *deleted = 0;
4418 }
4419 return REDISMODULE_OK;
4420}
4421
4422/* On success retrieve the double score associated at the sorted set element
4423 * 'ele' and returns REDISMODULE_OK. Otherwise REDISMODULE_ERR is returned
4424 * to signal one of the following conditions:
4425 *
4426 * * There is no such element 'ele' in the sorted set.
4427 * * The key is not a sorted set.
4428 * * The key is an open empty key.
4429 */
4430int RM_ZsetScore(RedisModuleKey *key, RedisModuleString *ele, double *score) {
4431 if (key->value == NULL) return REDISMODULE_ERR;
4432 if (key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
4433 if (zsetScore(key->value,ele->ptr,score) == C_ERR) return REDISMODULE_ERR;
4434 return REDISMODULE_OK;
4435}
4436
4437/* --------------------------------------------------------------------------
4438 * ## Key API for Sorted Set iterator
4439 * -------------------------------------------------------------------------- */
4440
4441void zsetKeyReset(RedisModuleKey *key) {
4442 key->u.zset.type = REDISMODULE_ZSET_RANGE_NONE;
4443 key->u.zset.current = NULL;
4444 key->u.zset.er = 1;
4445}
4446
4447/* Stop a sorted set iteration. */
4448void RM_ZsetRangeStop(RedisModuleKey *key) {
4449 if (!key->value || key->value->type != OBJ_ZSET) return;
4450 /* Free resources if needed. */
4451 if (key->u.zset.type == REDISMODULE_ZSET_RANGE_LEX)
4452 zslFreeLexRange(&key->u.zset.lrs);
4453 /* Setup sensible values so that misused iteration API calls when an
4454 * iterator is not active will result into something more sensible
4455 * than crashing. */
4456 zsetKeyReset(key);
4457}
4458
4459/* Return the "End of range" flag value to signal the end of the iteration. */
4460int RM_ZsetRangeEndReached(RedisModuleKey *key) {
4461 if (!key->value || key->value->type != OBJ_ZSET) return 1;
4462 return key->u.zset.er;
4463}
4464
4465/* Helper function for RM_ZsetFirstInScoreRange() and RM_ZsetLastInScoreRange().
4466 * Setup the sorted set iteration according to the specified score range
4467 * (see the functions calling it for more info). If 'first' is true the
4468 * first element in the range is used as a starting point for the iterator
4469 * otherwise the last. Return REDISMODULE_OK on success otherwise
4470 * REDISMODULE_ERR. */
4471int zsetInitScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex, int first) {
4472 if (!key->value || key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
4473
4474 RM_ZsetRangeStop(key);
4475 key->u.zset.type = REDISMODULE_ZSET_RANGE_SCORE;
4476 key->u.zset.er = 0;
4477
4478 /* Setup the range structure used by the sorted set core implementation
4479 * in order to seek at the specified element. */
4480 zrangespec *zrs = &key->u.zset.rs;
4481 zrs->min = min;
4482 zrs->max = max;
4483 zrs->minex = minex;
4484 zrs->maxex = maxex;
4485
4486 if (key->value->encoding == OBJ_ENCODING_LISTPACK) {
4487 key->u.zset.current = first ? zzlFirstInRange(key->value->ptr,zrs) :
4488 zzlLastInRange(key->value->ptr,zrs);
4489 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
4490 zset *zs = key->value->ptr;
4491 zskiplist *zsl = zs->zsl;
4492 key->u.zset.current = first ? zslFirstInRange(zsl,zrs) :
4493 zslLastInRange(zsl,zrs);
4494 } else {
4495 serverPanic("Unsupported zset encoding");
4496 }
4497 if (key->u.zset.current == NULL) key->u.zset.er = 1;
4498 return REDISMODULE_OK;
4499}
4500
4501/* Setup a sorted set iterator seeking the first element in the specified
4502 * range. Returns REDISMODULE_OK if the iterator was correctly initialized
4503 * otherwise REDISMODULE_ERR is returned in the following conditions:
4504 *
4505 * 1. The value stored at key is not a sorted set or the key is empty.
4506 *
4507 * The range is specified according to the two double values 'min' and 'max'.
4508 * Both can be infinite using the following two macros:
4509 *
4510 * * REDISMODULE_POSITIVE_INFINITE for positive infinite value
4511 * * REDISMODULE_NEGATIVE_INFINITE for negative infinite value
4512 *
4513 * 'minex' and 'maxex' parameters, if true, respectively setup a range
4514 * where the min and max value are exclusive (not included) instead of
4515 * inclusive. */
4516int RM_ZsetFirstInScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex) {
4517 return zsetInitScoreRange(key,min,max,minex,maxex,1);
4518}
4519
4520/* Exactly like RedisModule_ZsetFirstInScoreRange() but the last element of
4521 * the range is selected for the start of the iteration instead. */
4522int RM_ZsetLastInScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex) {
4523 return zsetInitScoreRange(key,min,max,minex,maxex,0);
4524}
4525
4526/* Helper function for RM_ZsetFirstInLexRange() and RM_ZsetLastInLexRange().
4527 * Setup the sorted set iteration according to the specified lexicographical
4528 * range (see the functions calling it for more info). If 'first' is true the
4529 * first element in the range is used as a starting point for the iterator
4530 * otherwise the last. Return REDISMODULE_OK on success otherwise
4531 * REDISMODULE_ERR.
4532 *
4533 * Note that this function takes 'min' and 'max' in the same form of the
4534 * Redis ZRANGEBYLEX command. */
4535int zsetInitLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max, int first) {
4536 if (!key->value || key->value->type != OBJ_ZSET) return REDISMODULE_ERR;
4537
4538 RM_ZsetRangeStop(key);
4539 key->u.zset.er = 0;
4540
4541 /* Setup the range structure used by the sorted set core implementation
4542 * in order to seek at the specified element. */
4543 zlexrangespec *zlrs = &key->u.zset.lrs;
4544 if (zslParseLexRange(min, max, zlrs) == C_ERR) return REDISMODULE_ERR;
4545
4546 /* Set the range type to lex only after successfully parsing the range,
4547 * otherwise we don't want the zlexrangespec to be freed. */
4548 key->u.zset.type = REDISMODULE_ZSET_RANGE_LEX;
4549
4550 if (key->value->encoding == OBJ_ENCODING_LISTPACK) {
4551 key->u.zset.current = first ? zzlFirstInLexRange(key->value->ptr,zlrs) :
4552 zzlLastInLexRange(key->value->ptr,zlrs);
4553 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
4554 zset *zs = key->value->ptr;
4555 zskiplist *zsl = zs->zsl;
4556 key->u.zset.current = first ? zslFirstInLexRange(zsl,zlrs) :
4557 zslLastInLexRange(zsl,zlrs);
4558 } else {
4559 serverPanic("Unsupported zset encoding");
4560 }
4561 if (key->u.zset.current == NULL) key->u.zset.er = 1;
4562
4563 return REDISMODULE_OK;
4564}
4565
4566/* Setup a sorted set iterator seeking the first element in the specified
4567 * lexicographical range. Returns REDISMODULE_OK if the iterator was correctly
4568 * initialized otherwise REDISMODULE_ERR is returned in the
4569 * following conditions:
4570 *
4571 * 1. The value stored at key is not a sorted set or the key is empty.
4572 * 2. The lexicographical range 'min' and 'max' format is invalid.
4573 *
4574 * 'min' and 'max' should be provided as two RedisModuleString objects
4575 * in the same format as the parameters passed to the ZRANGEBYLEX command.
4576 * The function does not take ownership of the objects, so they can be released
4577 * ASAP after the iterator is setup. */
4578int RM_ZsetFirstInLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max) {
4579 return zsetInitLexRange(key,min,max,1);
4580}
4581
4582/* Exactly like RedisModule_ZsetFirstInLexRange() but the last element of
4583 * the range is selected for the start of the iteration instead. */
4584int RM_ZsetLastInLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max) {
4585 return zsetInitLexRange(key,min,max,0);
4586}
4587
4588/* Return the current sorted set element of an active sorted set iterator
4589 * or NULL if the range specified in the iterator does not include any
4590 * element. */
4591RedisModuleString *RM_ZsetRangeCurrentElement(RedisModuleKey *key, double *score) {
4592 RedisModuleString *str;
4593
4594 if (!key->value || key->value->type != OBJ_ZSET) return NULL;
4595 if (key->u.zset.current == NULL) return NULL;
4596 if (key->value->encoding == OBJ_ENCODING_LISTPACK) {
4597 unsigned char *eptr, *sptr;
4598 eptr = key->u.zset.current;
4599 sds ele = lpGetObject(eptr);
4600 if (score) {
4601 sptr = lpNext(key->value->ptr,eptr);
4602 *score = zzlGetScore(sptr);
4603 }
4604 str = createObject(OBJ_STRING,ele);
4605 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
4606 zskiplistNode *ln = key->u.zset.current;
4607 if (score) *score = ln->score;
4608 str = createStringObject(ln->ele,sdslen(ln->ele));
4609 } else {
4610 serverPanic("Unsupported zset encoding");
4611 }
4612 autoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,str);
4613 return str;
4614}
4615
4616/* Go to the next element of the sorted set iterator. Returns 1 if there was
4617 * a next element, 0 if we are already at the latest element or the range
4618 * does not include any item at all. */
4619int RM_ZsetRangeNext(RedisModuleKey *key) {
4620 if (!key->value || key->value->type != OBJ_ZSET) return 0;
4621 if (!key->u.zset.type || !key->u.zset.current) return 0; /* No active iterator. */
4622
4623 if (key->value->encoding == OBJ_ENCODING_LISTPACK) {
4624 unsigned char *zl = key->value->ptr;
4625 unsigned char *eptr = key->u.zset.current;
4626 unsigned char *next;
4627 next = lpNext(zl,eptr); /* Skip element. */
4628 if (next) next = lpNext(zl,next); /* Skip score. */
4629 if (next == NULL) {
4630 key->u.zset.er = 1;
4631 return 0;
4632 } else {
4633 /* Are we still within the range? */
4634 if (key->u.zset.type == REDISMODULE_ZSET_RANGE_SCORE) {
4635 /* Fetch the next element score for the
4636 * range check. */
4637 unsigned char *saved_next = next;
4638 next = lpNext(zl,next); /* Skip next element. */
4639 double score = zzlGetScore(next); /* Obtain the next score. */
4640 if (!zslValueLteMax(score,&key->u.zset.rs)) {
4641 key->u.zset.er = 1;
4642 return 0;
4643 }
4644 next = saved_next;
4645 } else if (key->u.zset.type == REDISMODULE_ZSET_RANGE_LEX) {
4646 if (!zzlLexValueLteMax(next,&key->u.zset.lrs)) {
4647 key->u.zset.er = 1;
4648 return 0;
4649 }
4650 }
4651 key->u.zset.current = next;
4652 return 1;
4653 }
4654 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
4655 zskiplistNode *ln = key->u.zset.current, *next = ln->level[0].forward;
4656 if (next == NULL) {
4657 key->u.zset.er = 1;
4658 return 0;
4659 } else {
4660 /* Are we still within the range? */
4661 if (key->u.zset.type == REDISMODULE_ZSET_RANGE_SCORE &&
4662 !zslValueLteMax(next->score,&key->u.zset.rs))
4663 {
4664 key->u.zset.er = 1;
4665 return 0;
4666 } else if (key->u.zset.type == REDISMODULE_ZSET_RANGE_LEX) {
4667 if (!zslLexValueLteMax(next->ele,&key->u.zset.lrs)) {
4668 key->u.zset.er = 1;
4669 return 0;
4670 }
4671 }
4672 key->u.zset.current = next;
4673 return 1;
4674 }
4675 } else {
4676 serverPanic("Unsupported zset encoding");
4677 }
4678}
4679
4680/* Go to the previous element of the sorted set iterator. Returns 1 if there was
4681 * a previous element, 0 if we are already at the first element or the range
4682 * does not include any item at all. */
4683int RM_ZsetRangePrev(RedisModuleKey *key) {
4684 if (!key->value || key->value->type != OBJ_ZSET) return 0;
4685 if (!key->u.zset.type || !key->u.zset.current) return 0; /* No active iterator. */
4686
4687 if (key->value->encoding == OBJ_ENCODING_LISTPACK) {
4688 unsigned char *zl = key->value->ptr;
4689 unsigned char *eptr = key->u.zset.current;
4690 unsigned char *prev;
4691 prev = lpPrev(zl,eptr); /* Go back to previous score. */
4692 if (prev) prev = lpPrev(zl,prev); /* Back to previous ele. */
4693 if (prev == NULL) {
4694 key->u.zset.er = 1;
4695 return 0;
4696 } else {
4697 /* Are we still within the range? */
4698 if (key->u.zset.type == REDISMODULE_ZSET_RANGE_SCORE) {
4699 /* Fetch the previous element score for the
4700 * range check. */
4701 unsigned char *saved_prev = prev;
4702 prev = lpNext(zl,prev); /* Skip element to get the score.*/
4703 double score = zzlGetScore(prev); /* Obtain the prev score. */
4704 if (!zslValueGteMin(score,&key->u.zset.rs)) {
4705 key->u.zset.er = 1;
4706 return 0;
4707 }
4708 prev = saved_prev;
4709 } else if (key->u.zset.type == REDISMODULE_ZSET_RANGE_LEX) {
4710 if (!zzlLexValueGteMin(prev,&key->u.zset.lrs)) {
4711 key->u.zset.er = 1;
4712 return 0;
4713 }
4714 }
4715 key->u.zset.current = prev;
4716 return 1;
4717 }
4718 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
4719 zskiplistNode *ln = key->u.zset.current, *prev = ln->backward;
4720 if (prev == NULL) {
4721 key->u.zset.er = 1;
4722 return 0;
4723 } else {
4724 /* Are we still within the range? */
4725 if (key->u.zset.type == REDISMODULE_ZSET_RANGE_SCORE &&
4726 !zslValueGteMin(prev->score,&key->u.zset.rs))
4727 {
4728 key->u.zset.er = 1;
4729 return 0;
4730 } else if (key->u.zset.type == REDISMODULE_ZSET_RANGE_LEX) {
4731 if (!zslLexValueGteMin(prev->ele,&key->u.zset.lrs)) {
4732 key->u.zset.er = 1;
4733 return 0;
4734 }
4735 }
4736 key->u.zset.current = prev;
4737 return 1;
4738 }
4739 } else {
4740 serverPanic("Unsupported zset encoding");
4741 }
4742}
4743
4744/* --------------------------------------------------------------------------
4745 * ## Key API for Hash type
4746 *
4747 * See also RM_ValueLength(), which returns the number of fields in a hash.
4748 * -------------------------------------------------------------------------- */
4749
4750/* Set the field of the specified hash field to the specified value.
4751 * If the key is an empty key open for writing, it is created with an empty
4752 * hash value, in order to set the specified field.
4753 *
4754 * The function is variadic and the user must specify pairs of field
4755 * names and values, both as RedisModuleString pointers (unless the
4756 * CFIELD option is set, see later). At the end of the field/value-ptr pairs,
4757 * NULL must be specified as last argument to signal the end of the arguments
4758 * in the variadic function.
4759 *
4760 * Example to set the hash argv[1] to the value argv[2]:
4761 *
4762 * RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[1],argv[2],NULL);
4763 *
4764 * The function can also be used in order to delete fields (if they exist)
4765 * by setting them to the specified value of REDISMODULE_HASH_DELETE:
4766 *
4767 * RedisModule_HashSet(key,REDISMODULE_HASH_NONE,argv[1],
4768 * REDISMODULE_HASH_DELETE,NULL);
4769 *
4770 * The behavior of the command changes with the specified flags, that can be
4771 * set to REDISMODULE_HASH_NONE if no special behavior is needed.
4772 *
4773 * REDISMODULE_HASH_NX: The operation is performed only if the field was not
4774 * already existing in the hash.
4775 * REDISMODULE_HASH_XX: The operation is performed only if the field was
4776 * already existing, so that a new value could be
4777 * associated to an existing filed, but no new fields
4778 * are created.
4779 * REDISMODULE_HASH_CFIELDS: The field names passed are null terminated C
4780 * strings instead of RedisModuleString objects.
4781 * REDISMODULE_HASH_COUNT_ALL: Include the number of inserted fields in the
4782 * returned number, in addition to the number of
4783 * updated and deleted fields. (Added in Redis
4784 * 6.2.)
4785 *
4786 * Unless NX is specified, the command overwrites the old field value with
4787 * the new one.
4788 *
4789 * When using REDISMODULE_HASH_CFIELDS, field names are reported using
4790 * normal C strings, so for example to delete the field "foo" the following
4791 * code can be used:
4792 *
4793 * RedisModule_HashSet(key,REDISMODULE_HASH_CFIELDS,"foo",
4794 * REDISMODULE_HASH_DELETE,NULL);
4795 *
4796 * Return value:
4797 *
4798 * The number of fields existing in the hash prior to the call, which have been
4799 * updated (its old value has been replaced by a new value) or deleted. If the
4800 * flag REDISMODULE_HASH_COUNT_ALL is set, inserted fields not previously
4801 * existing in the hash are also counted.
4802 *
4803 * If the return value is zero, `errno` is set (since Redis 6.2) as follows:
4804 *
4805 * - EINVAL if any unknown flags are set or if key is NULL.
4806 * - ENOTSUP if the key is associated with a non Hash value.
4807 * - EBADF if the key was not opened for writing.
4808 * - ENOENT if no fields were counted as described under Return value above.
4809 * This is not actually an error. The return value can be zero if all fields
4810 * were just created and the COUNT_ALL flag was unset, or if changes were held
4811 * back due to the NX and XX flags.
4812 *
4813 * NOTICE: The return value semantics of this function are very different
4814 * between Redis 6.2 and older versions. Modules that use it should determine
4815 * the Redis version and handle it accordingly.
4816 */
4817int RM_HashSet(RedisModuleKey *key, int flags, ...) {
4818 va_list ap;
4819 if (!key || (flags & ~(REDISMODULE_HASH_NX |
4820 REDISMODULE_HASH_XX |
4821 REDISMODULE_HASH_CFIELDS |
4822 REDISMODULE_HASH_COUNT_ALL))) {
4823 errno = EINVAL;
4824 return 0;
4825 } else if (key->value && key->value->type != OBJ_HASH) {
4826 errno = ENOTSUP;
4827 return 0;
4828 } else if (!(key->mode & REDISMODULE_WRITE)) {
4829 errno = EBADF;
4830 return 0;
4831 }
4832 if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_HASH);
4833
4834 int count = 0;
4835 va_start(ap, flags);
4836 while(1) {
4837 RedisModuleString *field, *value;
4838 /* Get the field and value objects. */
4839 if (flags & REDISMODULE_HASH_CFIELDS) {
4840 char *cfield = va_arg(ap,char*);
4841 if (cfield == NULL) break;
4842 field = createRawStringObject(cfield,strlen(cfield));
4843 } else {
4844 field = va_arg(ap,RedisModuleString*);
4845 if (field == NULL) break;
4846 }
4847 value = va_arg(ap,RedisModuleString*);
4848
4849 /* Handle XX and NX */
4850 if (flags & (REDISMODULE_HASH_XX|REDISMODULE_HASH_NX)) {
4851 int exists = hashTypeExists(key->value, field->ptr);
4852 if (((flags & REDISMODULE_HASH_XX) && !exists) ||
4853 ((flags & REDISMODULE_HASH_NX) && exists))
4854 {
4855 if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field);
4856 continue;
4857 }
4858 }
4859
4860 /* Handle deletion if value is REDISMODULE_HASH_DELETE. */
4861 if (value == REDISMODULE_HASH_DELETE) {
4862 count += hashTypeDelete(key->value, field->ptr);
4863 if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field);
4864 continue;
4865 }
4866
4867 int low_flags = HASH_SET_COPY;
4868 /* If CFIELDS is active, we can pass the ownership of the
4869 * SDS object to the low level function that sets the field
4870 * to avoid a useless copy. */
4871 if (flags & REDISMODULE_HASH_CFIELDS)
4872 low_flags |= HASH_SET_TAKE_FIELD;
4873
4874 robj *argv[2] = {field,value};
4875 hashTypeTryConversion(key->value,argv,0,1);
4876 int updated = hashTypeSet(key->value, field->ptr, value->ptr, low_flags);
4877 count += (flags & REDISMODULE_HASH_COUNT_ALL) ? 1 : updated;
4878
4879 /* If CFIELDS is active, SDS string ownership is now of hashTypeSet(),
4880 * however we still have to release the 'field' object shell. */
4881 if (flags & REDISMODULE_HASH_CFIELDS) {
4882 field->ptr = NULL; /* Prevent the SDS string from being freed. */
4883 decrRefCount(field);
4884 }
4885 }
4886 va_end(ap);
4887 moduleDelKeyIfEmpty(key);
4888 if (count == 0) errno = ENOENT;
4889 return count;
4890}
4891
4892/* Get fields from a hash value. This function is called using a variable
4893 * number of arguments, alternating a field name (as a RedisModuleString
4894 * pointer) with a pointer to a RedisModuleString pointer, that is set to the
4895 * value of the field if the field exists, or NULL if the field does not exist.
4896 * At the end of the field/value-ptr pairs, NULL must be specified as last
4897 * argument to signal the end of the arguments in the variadic function.
4898 *
4899 * This is an example usage:
4900 *
4901 * RedisModuleString *first, *second;
4902 * RedisModule_HashGet(mykey,REDISMODULE_HASH_NONE,argv[1],&first,
4903 * argv[2],&second,NULL);
4904 *
4905 * As with RedisModule_HashSet() the behavior of the command can be specified
4906 * passing flags different than REDISMODULE_HASH_NONE:
4907 *
4908 * REDISMODULE_HASH_CFIELDS: field names as null terminated C strings.
4909 *
4910 * REDISMODULE_HASH_EXISTS: instead of setting the value of the field
4911 * expecting a RedisModuleString pointer to pointer, the function just
4912 * reports if the field exists or not and expects an integer pointer
4913 * as the second element of each pair.
4914 *
4915 * Example of REDISMODULE_HASH_CFIELDS:
4916 *
4917 * RedisModuleString *username, *hashedpass;
4918 * RedisModule_HashGet(mykey,REDISMODULE_HASH_CFIELDS,"username",&username,"hp",&hashedpass, NULL);
4919 *
4920 * Example of REDISMODULE_HASH_EXISTS:
4921 *
4922 * int exists;
4923 * RedisModule_HashGet(mykey,REDISMODULE_HASH_EXISTS,argv[1],&exists,NULL);
4924 *
4925 * The function returns REDISMODULE_OK on success and REDISMODULE_ERR if
4926 * the key is not a hash value.
4927 *
4928 * Memory management:
4929 *
4930 * The returned RedisModuleString objects should be released with
4931 * RedisModule_FreeString(), or by enabling automatic memory management.
4932 */
4933int RM_HashGet(RedisModuleKey *key, int flags, ...) {
4934 va_list ap;
4935 if (key->value && key->value->type != OBJ_HASH) return REDISMODULE_ERR;
4936
4937 va_start(ap, flags);
4938 while(1) {
4939 RedisModuleString *field, **valueptr;
4940 int *existsptr;
4941 /* Get the field object and the value pointer to pointer. */
4942 if (flags & REDISMODULE_HASH_CFIELDS) {
4943 char *cfield = va_arg(ap,char*);
4944 if (cfield == NULL) break;
4945 field = createRawStringObject(cfield,strlen(cfield));
4946 } else {
4947 field = va_arg(ap,RedisModuleString*);
4948 if (field == NULL) break;
4949 }
4950
4951 /* Query the hash for existence or value object. */
4952 if (flags & REDISMODULE_HASH_EXISTS) {
4953 existsptr = va_arg(ap,int*);
4954 if (key->value)
4955 *existsptr = hashTypeExists(key->value,field->ptr);
4956 else
4957 *existsptr = 0;
4958 } else {
4959 valueptr = va_arg(ap,RedisModuleString**);
4960 if (key->value) {
4961 *valueptr = hashTypeGetValueObject(key->value,field->ptr);
4962 if (*valueptr) {
4963 robj *decoded = getDecodedObject(*valueptr);
4964 decrRefCount(*valueptr);
4965 *valueptr = decoded;
4966 }
4967 if (*valueptr)
4968 autoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,*valueptr);
4969 } else {
4970 *valueptr = NULL;
4971 }
4972 }
4973
4974 /* Cleanup */
4975 if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field);
4976 }
4977 va_end(ap);
4978 return REDISMODULE_OK;
4979}
4980
4981/* --------------------------------------------------------------------------
4982 * ## Key API for Stream type
4983 *
4984 * For an introduction to streams, see https://redis.io/topics/streams-intro.
4985 *
4986 * The type RedisModuleStreamID, which is used in stream functions, is a struct
4987 * with two 64-bit fields and is defined as
4988 *
4989 * typedef struct RedisModuleStreamID {
4990 * uint64_t ms;
4991 * uint64_t seq;
4992 * } RedisModuleStreamID;
4993 *
4994 * See also RM_ValueLength(), which returns the length of a stream, and the
4995 * conversion functions RM_StringToStreamID() and RM_CreateStringFromStreamID().
4996 * -------------------------------------------------------------------------- */
4997
4998/* Adds an entry to a stream. Like XADD without trimming.
4999 *
5000 * - `key`: The key where the stream is (or will be) stored
5001 * - `flags`: A bit field of
5002 * - `REDISMODULE_STREAM_ADD_AUTOID`: Assign a stream ID automatically, like
5003 * `*` in the XADD command.
5004 * - `id`: If the `AUTOID` flag is set, this is where the assigned ID is
5005 * returned. Can be NULL if `AUTOID` is set, if you don't care to receive the
5006 * ID. If `AUTOID` is not set, this is the requested ID.
5007 * - `argv`: A pointer to an array of size `numfields * 2` containing the
5008 * fields and values.
5009 * - `numfields`: The number of field-value pairs in `argv`.
5010 *
5011 * Returns REDISMODULE_OK if an entry has been added. On failure,
5012 * REDISMODULE_ERR is returned and `errno` is set as follows:
5013 *
5014 * - EINVAL if called with invalid arguments
5015 * - ENOTSUP if the key refers to a value of a type other than stream
5016 * - EBADF if the key was not opened for writing
5017 * - EDOM if the given ID was 0-0 or not greater than all other IDs in the
5018 * stream (only if the AUTOID flag is unset)
5019 * - EFBIG if the stream has reached the last possible ID
5020 * - ERANGE if the elements are too large to be stored.
5021 */
5022int RM_StreamAdd(RedisModuleKey *key, int flags, RedisModuleStreamID *id, RedisModuleString **argv, long numfields) {
5023 /* Validate args */
5024 if (!key || (numfields != 0 && !argv) || /* invalid key or argv */
5025 (flags & ~(REDISMODULE_STREAM_ADD_AUTOID)) || /* invalid flags */
5026 (!(flags & REDISMODULE_STREAM_ADD_AUTOID) && !id)) { /* id required */
5027 errno = EINVAL;
5028 return REDISMODULE_ERR;
5029 } else if (key->value && key->value->type != OBJ_STREAM) {
5030 errno = ENOTSUP; /* wrong type */
5031 return REDISMODULE_ERR;
5032 } else if (!(key->mode & REDISMODULE_WRITE)) {
5033 errno = EBADF; /* key not open for writing */
5034 return REDISMODULE_ERR;
5035 } else if (!(flags & REDISMODULE_STREAM_ADD_AUTOID) &&
5036 id->ms == 0 && id->seq == 0) {
5037 errno = EDOM; /* ID out of range */
5038 return REDISMODULE_ERR;
5039 }
5040
5041 /* Create key if necessary */
5042 int created = 0;
5043 if (key->value == NULL) {
5044 moduleCreateEmptyKey(key, REDISMODULE_KEYTYPE_STREAM);
5045 created = 1;
5046 }
5047
5048 stream *s = key->value->ptr;
5049 if (s->last_id.ms == UINT64_MAX && s->last_id.seq == UINT64_MAX) {
5050 /* The stream has reached the last possible ID */
5051 errno = EFBIG;
5052 return REDISMODULE_ERR;
5053 }
5054
5055 streamID added_id;
5056 streamID use_id;
5057 streamID *use_id_ptr = NULL;
5058 if (!(flags & REDISMODULE_STREAM_ADD_AUTOID)) {
5059 use_id.ms = id->ms;
5060 use_id.seq = id->seq;
5061 use_id_ptr = &use_id;
5062 }
5063
5064 if (streamAppendItem(s,argv,numfields,&added_id,use_id_ptr,1) == C_ERR) {
5065 /* Either the ID not greater than all existing IDs in the stream, or
5066 * the elements are too large to be stored. either way, errno is already
5067 * set by streamAppendItem. */
5068 return REDISMODULE_ERR;
5069 }
5070 /* Postponed signalKeyAsReady(). Done implicitly by moduleCreateEmptyKey()
5071 * so not needed if the stream has just been created. */
5072 if (!created) key->u.stream.signalready = 1;
5073
5074 if (id != NULL) {
5075 id->ms = added_id.ms;
5076 id->seq = added_id.seq;
5077 }
5078
5079 return REDISMODULE_OK;
5080}
5081
5082/* Deletes an entry from a stream.
5083 *
5084 * - `key`: A key opened for writing, with no stream iterator started.
5085 * - `id`: The stream ID of the entry to delete.
5086 *
5087 * Returns REDISMODULE_OK on success. On failure, REDISMODULE_ERR is returned
5088 * and `errno` is set as follows:
5089 *
5090 * - EINVAL if called with invalid arguments
5091 * - ENOTSUP if the key refers to a value of a type other than stream or if the
5092 * key is empty
5093 * - EBADF if the key was not opened for writing or if a stream iterator is
5094 * associated with the key
5095 * - ENOENT if no entry with the given stream ID exists
5096 *
5097 * See also RM_StreamIteratorDelete() for deleting the current entry while
5098 * iterating using a stream iterator.
5099 */
5100int RM_StreamDelete(RedisModuleKey *key, RedisModuleStreamID *id) {
5101 if (!key || !id) {
5102 errno = EINVAL;
5103 return REDISMODULE_ERR;
5104 } else if (!key->value || key->value->type != OBJ_STREAM) {
5105 errno = ENOTSUP; /* wrong type */
5106 return REDISMODULE_ERR;
5107 } else if (!(key->mode & REDISMODULE_WRITE) ||
5108 key->iter != NULL) {
5109 errno = EBADF; /* key not opened for writing or iterator started */
5110 return REDISMODULE_ERR;
5111 }
5112 stream *s = key->value->ptr;
5113 streamID streamid = {id->ms, id->seq};
5114 if (streamDeleteItem(s, &streamid)) {
5115 return REDISMODULE_OK;
5116 } else {
5117 errno = ENOENT; /* no entry with this id */
5118 return REDISMODULE_ERR;
5119 }
5120}
5121
5122/* Sets up a stream iterator.
5123 *
5124 * - `key`: The stream key opened for reading using RedisModule_OpenKey().
5125 * - `flags`:
5126 * - `REDISMODULE_STREAM_ITERATOR_EXCLUSIVE`: Don't include `start` and `end`
5127 * in the iterated range.
5128 * - `REDISMODULE_STREAM_ITERATOR_REVERSE`: Iterate in reverse order, starting
5129 * from the `end` of the range.
5130 * - `start`: The lower bound of the range. Use NULL for the beginning of the
5131 * stream.
5132 * - `end`: The upper bound of the range. Use NULL for the end of the stream.
5133 *
5134 * Returns REDISMODULE_OK on success. On failure, REDISMODULE_ERR is returned
5135 * and `errno` is set as follows:
5136 *
5137 * - EINVAL if called with invalid arguments
5138 * - ENOTSUP if the key refers to a value of a type other than stream or if the
5139 * key is empty
5140 * - EBADF if the key was not opened for writing or if a stream iterator is
5141 * already associated with the key
5142 * - EDOM if `start` or `end` is outside the valid range
5143 *
5144 * Returns REDISMODULE_OK on success and REDISMODULE_ERR if the key doesn't
5145 * refer to a stream or if invalid arguments were given.
5146 *
5147 * The stream IDs are retrieved using RedisModule_StreamIteratorNextID() and
5148 * for each stream ID, the fields and values are retrieved using
5149 * RedisModule_StreamIteratorNextField(). The iterator is freed by calling
5150 * RedisModule_StreamIteratorStop().
5151 *
5152 * Example (error handling omitted):
5153 *
5154 * RedisModule_StreamIteratorStart(key, 0, startid_ptr, endid_ptr);
5155 * RedisModuleStreamID id;
5156 * long numfields;
5157 * while (RedisModule_StreamIteratorNextID(key, &id, &numfields) ==
5158 * REDISMODULE_OK) {
5159 * RedisModuleString *field, *value;
5160 * while (RedisModule_StreamIteratorNextField(key, &field, &value) ==
5161 * REDISMODULE_OK) {
5162 * //
5163 * // ... Do stuff ...
5164 * //
5165 * RedisModule_FreeString(ctx, field);
5166 * RedisModule_FreeString(ctx, value);
5167 * }
5168 * }
5169 * RedisModule_StreamIteratorStop(key);
5170 */
5171int RM_StreamIteratorStart(RedisModuleKey *key, int flags, RedisModuleStreamID *start, RedisModuleStreamID *end) {
5172 /* check args */
5173 if (!key ||
5174 (flags & ~(REDISMODULE_STREAM_ITERATOR_EXCLUSIVE |
5175 REDISMODULE_STREAM_ITERATOR_REVERSE))) {
5176 errno = EINVAL; /* key missing or invalid flags */
5177 return REDISMODULE_ERR;
5178 } else if (!key->value || key->value->type != OBJ_STREAM) {
5179 errno = ENOTSUP;
5180 return REDISMODULE_ERR; /* not a stream */
5181 } else if (key->iter) {
5182 errno = EBADF; /* iterator already started */
5183 return REDISMODULE_ERR;
5184 }
5185
5186 /* define range for streamIteratorStart() */
5187 streamID lower, upper;
5188 if (start) lower = (streamID){start->ms, start->seq};
5189 if (end) upper = (streamID){end->ms, end->seq};
5190 if (flags & REDISMODULE_STREAM_ITERATOR_EXCLUSIVE) {
5191 if ((start && streamIncrID(&lower) != C_OK) ||
5192 (end && streamDecrID(&upper) != C_OK)) {
5193 errno = EDOM; /* end is 0-0 or start is MAX-MAX? */
5194 return REDISMODULE_ERR;
5195 }
5196 }
5197
5198 /* create iterator */
5199 stream *s = key->value->ptr;
5200 int rev = flags & REDISMODULE_STREAM_ITERATOR_REVERSE;
5201 streamIterator *si = zmalloc(sizeof(*si));
5202 streamIteratorStart(si, s, start ? &lower : NULL, end ? &upper : NULL, rev);
5203 key->iter = si;
5204 key->u.stream.currentid.ms = 0; /* for RM_StreamIteratorDelete() */
5205 key->u.stream.currentid.seq = 0;
5206 key->u.stream.numfieldsleft = 0; /* for RM_StreamIteratorNextField() */
5207 return REDISMODULE_OK;
5208}
5209
5210/* Stops a stream iterator created using RedisModule_StreamIteratorStart() and
5211 * reclaims its memory.
5212 *
5213 * Returns REDISMODULE_OK on success. On failure, REDISMODULE_ERR is returned
5214 * and `errno` is set as follows:
5215 *
5216 * - EINVAL if called with a NULL key
5217 * - ENOTSUP if the key refers to a value of a type other than stream or if the
5218 * key is empty
5219 * - EBADF if the key was not opened for writing or if no stream iterator is
5220 * associated with the key
5221 */
5222int RM_StreamIteratorStop(RedisModuleKey *key) {
5223 if (!key) {
5224 errno = EINVAL;
5225 return REDISMODULE_ERR;
5226 } else if (!key->value || key->value->type != OBJ_STREAM) {
5227 errno = ENOTSUP;
5228 return REDISMODULE_ERR;
5229 } else if (!key->iter) {
5230 errno = EBADF;
5231 return REDISMODULE_ERR;
5232 }
5233 streamIteratorStop(key->iter);
5234 zfree(key->iter);
5235 key->iter = NULL;
5236 return REDISMODULE_OK;
5237}
5238
5239/* Finds the next stream entry and returns its stream ID and the number of
5240 * fields.
5241 *
5242 * - `key`: Key for which a stream iterator has been started using
5243 * RedisModule_StreamIteratorStart().
5244 * - `id`: The stream ID returned. NULL if you don't care.
5245 * - `numfields`: The number of fields in the found stream entry. NULL if you
5246 * don't care.
5247 *
5248 * Returns REDISMODULE_OK and sets `*id` and `*numfields` if an entry was found.
5249 * On failure, REDISMODULE_ERR is returned and `errno` is set as follows:
5250 *
5251 * - EINVAL if called with a NULL key
5252 * - ENOTSUP if the key refers to a value of a type other than stream or if the
5253 * key is empty
5254 * - EBADF if no stream iterator is associated with the key
5255 * - ENOENT if there are no more entries in the range of the iterator
5256 *
5257 * In practice, if RM_StreamIteratorNextID() is called after a successful call
5258 * to RM_StreamIteratorStart() and with the same key, it is safe to assume that
5259 * an REDISMODULE_ERR return value means that there are no more entries.
5260 *
5261 * Use RedisModule_StreamIteratorNextField() to retrieve the fields and values.
5262 * See the example at RedisModule_StreamIteratorStart().
5263 */
5264int RM_StreamIteratorNextID(RedisModuleKey *key, RedisModuleStreamID *id, long *numfields) {
5265 if (!key) {
5266 errno = EINVAL;
5267 return REDISMODULE_ERR;
5268 } else if (!key->value || key->value->type != OBJ_STREAM) {
5269 errno = ENOTSUP;
5270 return REDISMODULE_ERR;
5271 } else if (!key->iter) {
5272 errno = EBADF;
5273 return REDISMODULE_ERR;
5274 }
5275 streamIterator *si = key->iter;
5276 int64_t *num_ptr = &key->u.stream.numfieldsleft;
5277 streamID *streamid_ptr = &key->u.stream.currentid;
5278 if (streamIteratorGetID(si, streamid_ptr, num_ptr)) {
5279 if (id) {
5280 id->ms = streamid_ptr->ms;
5281 id->seq = streamid_ptr->seq;
5282 }
5283 if (numfields) *numfields = *num_ptr;
5284 return REDISMODULE_OK;
5285 } else {
5286 /* No entry found. */
5287 key->u.stream.currentid.ms = 0; /* for RM_StreamIteratorDelete() */
5288 key->u.stream.currentid.seq = 0;
5289 key->u.stream.numfieldsleft = 0; /* for RM_StreamIteratorNextField() */
5290 errno = ENOENT;
5291 return REDISMODULE_ERR;
5292 }
5293}
5294
5295/* Retrieves the next field of the current stream ID and its corresponding value
5296 * in a stream iteration. This function should be called repeatedly after calling
5297 * RedisModule_StreamIteratorNextID() to fetch each field-value pair.
5298 *
5299 * - `key`: Key where a stream iterator has been started.
5300 * - `field_ptr`: This is where the field is returned.
5301 * - `value_ptr`: This is where the value is returned.
5302 *
5303 * Returns REDISMODULE_OK and points `*field_ptr` and `*value_ptr` to freshly
5304 * allocated RedisModuleString objects. The string objects are freed
5305 * automatically when the callback finishes if automatic memory is enabled. On
5306 * failure, REDISMODULE_ERR is returned and `errno` is set as follows:
5307 *
5308 * - EINVAL if called with a NULL key
5309 * - ENOTSUP if the key refers to a value of a type other than stream or if the
5310 * key is empty
5311 * - EBADF if no stream iterator is associated with the key
5312 * - ENOENT if there are no more fields in the current stream entry
5313 *
5314 * In practice, if RM_StreamIteratorNextField() is called after a successful
5315 * call to RM_StreamIteratorNextID() and with the same key, it is safe to assume
5316 * that an REDISMODULE_ERR return value means that there are no more fields.
5317 *
5318 * See the example at RedisModule_StreamIteratorStart().
5319 */
5320int RM_StreamIteratorNextField(RedisModuleKey *key, RedisModuleString **field_ptr, RedisModuleString **value_ptr) {
5321 if (!key) {
5322 errno = EINVAL;
5323 return REDISMODULE_ERR;
5324 } else if (!key->value || key->value->type != OBJ_STREAM) {
5325 errno = ENOTSUP;
5326 return REDISMODULE_ERR;
5327 } else if (!key->iter) {
5328 errno = EBADF;
5329 return REDISMODULE_ERR;
5330 } else if (key->u.stream.numfieldsleft <= 0) {
5331 errno = ENOENT;
5332 return REDISMODULE_ERR;
5333 }
5334 streamIterator *si = key->iter;
5335 unsigned char *field, *value;
5336 int64_t field_len, value_len;
5337 streamIteratorGetField(si, &field, &value, &field_len, &value_len);
5338 if (field_ptr) {
5339 *field_ptr = createRawStringObject((char *)field, field_len);
5340 autoMemoryAdd(key->ctx, REDISMODULE_AM_STRING, *field_ptr);
5341 }
5342 if (value_ptr) {
5343 *value_ptr = createRawStringObject((char *)value, value_len);
5344 autoMemoryAdd(key->ctx, REDISMODULE_AM_STRING, *value_ptr);
5345 }
5346 key->u.stream.numfieldsleft--;
5347 return REDISMODULE_OK;
5348}
5349
5350/* Deletes the current stream entry while iterating.
5351 *
5352 * This function can be called after RM_StreamIteratorNextID() or after any
5353 * calls to RM_StreamIteratorNextField().
5354 *
5355 * Returns REDISMODULE_OK on success. On failure, REDISMODULE_ERR is returned
5356 * and `errno` is set as follows:
5357 *
5358 * - EINVAL if key is NULL
5359 * - ENOTSUP if the key is empty or is of another type than stream
5360 * - EBADF if the key is not opened for writing, if no iterator has been started
5361 * - ENOENT if the iterator has no current stream entry
5362 */
5363int RM_StreamIteratorDelete(RedisModuleKey *key) {
5364 if (!key) {
5365 errno = EINVAL;
5366 return REDISMODULE_ERR;
5367 } else if (!key->value || key->value->type != OBJ_STREAM) {
5368 errno = ENOTSUP;
5369 return REDISMODULE_ERR;
5370 } else if (!(key->mode & REDISMODULE_WRITE) || !key->iter) {
5371 errno = EBADF;
5372 return REDISMODULE_ERR;
5373 } else if (key->u.stream.currentid.ms == 0 &&
5374 key->u.stream.currentid.seq == 0) {
5375 errno = ENOENT;
5376 return REDISMODULE_ERR;
5377 }
5378 streamIterator *si = key->iter;
5379 streamIteratorRemoveEntry(si, &key->u.stream.currentid);
5380 key->u.stream.currentid.ms = 0; /* Make sure repeated Delete() fails */
5381 key->u.stream.currentid.seq = 0;
5382 key->u.stream.numfieldsleft = 0; /* Make sure NextField() fails */
5383 return REDISMODULE_OK;
5384}
5385
5386/* Trim a stream by length, similar to XTRIM with MAXLEN.
5387 *
5388 * - `key`: Key opened for writing.
5389 * - `flags`: A bitfield of
5390 * - `REDISMODULE_STREAM_TRIM_APPROX`: Trim less if it improves performance,
5391 * like XTRIM with `~`.
5392 * - `length`: The number of stream entries to keep after trimming.
5393 *
5394 * Returns the number of entries deleted. On failure, a negative value is
5395 * returned and `errno` is set as follows:
5396 *
5397 * - EINVAL if called with invalid arguments
5398 * - ENOTSUP if the key is empty or of a type other than stream
5399 * - EBADF if the key is not opened for writing
5400 */
5401long long RM_StreamTrimByLength(RedisModuleKey *key, int flags, long long length) {
5402 if (!key || (flags & ~(REDISMODULE_STREAM_TRIM_APPROX)) || length < 0) {
5403 errno = EINVAL;
5404 return -1;
5405 } else if (!key->value || key->value->type != OBJ_STREAM) {
5406 errno = ENOTSUP;
5407 return -1;
5408 } else if (!(key->mode & REDISMODULE_WRITE)) {
5409 errno = EBADF;
5410 return -1;
5411 }
5412 int approx = flags & REDISMODULE_STREAM_TRIM_APPROX ? 1 : 0;
5413 return streamTrimByLength((stream *)key->value->ptr, length, approx);
5414}
5415
5416/* Trim a stream by ID, similar to XTRIM with MINID.
5417 *
5418 * - `key`: Key opened for writing.
5419 * - `flags`: A bitfield of
5420 * - `REDISMODULE_STREAM_TRIM_APPROX`: Trim less if it improves performance,
5421 * like XTRIM with `~`.
5422 * - `id`: The smallest stream ID to keep after trimming.
5423 *
5424 * Returns the number of entries deleted. On failure, a negative value is
5425 * returned and `errno` is set as follows:
5426 *
5427 * - EINVAL if called with invalid arguments
5428 * - ENOTSUP if the key is empty or of a type other than stream
5429 * - EBADF if the key is not opened for writing
5430 */
5431long long RM_StreamTrimByID(RedisModuleKey *key, int flags, RedisModuleStreamID *id) {
5432 if (!key || (flags & ~(REDISMODULE_STREAM_TRIM_APPROX)) || !id) {
5433 errno = EINVAL;
5434 return -1;
5435 } else if (!key->value || key->value->type != OBJ_STREAM) {
5436 errno = ENOTSUP;
5437 return -1;
5438 } else if (!(key->mode & REDISMODULE_WRITE)) {
5439 errno = EBADF;
5440 return -1;
5441 }
5442 int approx = flags & REDISMODULE_STREAM_TRIM_APPROX ? 1 : 0;
5443 streamID minid = (streamID){id->ms, id->seq};
5444 return streamTrimByID((stream *)key->value->ptr, minid, approx);
5445}
5446
5447/* --------------------------------------------------------------------------
5448 * ## Calling Redis commands from modules
5449 *
5450 * RM_Call() sends a command to Redis. The remaining functions handle the reply.
5451 * -------------------------------------------------------------------------- */
5452
5453
5454void moduleParseCallReply_Int(RedisModuleCallReply *reply);
5455void moduleParseCallReply_BulkString(RedisModuleCallReply *reply);
5456void moduleParseCallReply_SimpleString(RedisModuleCallReply *reply);
5457void moduleParseCallReply_Array(RedisModuleCallReply *reply);
5458
5459
5460
5461
5462/* Free a Call reply and all the nested replies it contains if it's an
5463 * array. */
5464void RM_FreeCallReply(RedisModuleCallReply *reply) {
5465 /* This is a wrapper for the recursive free reply function. This is needed
5466 * in order to have the first level function to return on nested replies,
5467 * but only if called by the module API. */
5468 RedisModuleCtx *ctx = callReplyGetPrivateData(reply);
5469 freeCallReply(reply);
5470 autoMemoryFreed(ctx,REDISMODULE_AM_REPLY,reply);
5471}
5472
5473/* Return the reply type as one of the following:
5474 *
5475 * - REDISMODULE_REPLY_UNKNOWN
5476 * - REDISMODULE_REPLY_STRING
5477 * - REDISMODULE_REPLY_ERROR
5478 * - REDISMODULE_REPLY_INTEGER
5479 * - REDISMODULE_REPLY_ARRAY
5480 * - REDISMODULE_REPLY_NULL
5481 * - REDISMODULE_REPLY_MAP
5482 * - REDISMODULE_REPLY_SET
5483 * - REDISMODULE_REPLY_BOOL
5484 * - REDISMODULE_REPLY_DOUBLE
5485 * - REDISMODULE_REPLY_BIG_NUMBER
5486 * - REDISMODULE_REPLY_VERBATIM_STRING
5487 * - REDISMODULE_REPLY_ATTRIBUTE */
5488int RM_CallReplyType(RedisModuleCallReply *reply) {
5489 return callReplyType(reply);
5490}
5491
5492/* Return the reply type length, where applicable. */
5493size_t RM_CallReplyLength(RedisModuleCallReply *reply) {
5494 return callReplyGetLen(reply);
5495}
5496
5497/* Return the 'idx'-th nested call reply element of an array reply, or NULL
5498 * if the reply type is wrong or the index is out of range. */
5499RedisModuleCallReply *RM_CallReplyArrayElement(RedisModuleCallReply *reply, size_t idx) {
5500 return callReplyGetArrayElement(reply, idx);
5501}
5502
5503/* Return the `long long` of an integer reply. */
5504long long RM_CallReplyInteger(RedisModuleCallReply *reply) {
5505 return callReplyGetLongLong(reply);
5506}
5507
5508/* Return the double value of a double reply. */
5509double RM_CallReplyDouble(RedisModuleCallReply *reply) {
5510 return callReplyGetDouble(reply);
5511}
5512
5513/* Return the big number value of a big number reply. */
5514const char *RM_CallReplyBigNumber(RedisModuleCallReply *reply, size_t *len) {
5515 return callReplyGetBigNumber(reply, len);
5516}
5517
5518/* Return the value of a verbatim string reply,
5519 * An optional output argument can be given to get verbatim reply format. */
5520const char *RM_CallReplyVerbatim(RedisModuleCallReply *reply, size_t *len, const char **format) {
5521 return callReplyGetVerbatim(reply, len, format);
5522}
5523
5524/* Return the Boolean value of a Boolean reply. */
5525int RM_CallReplyBool(RedisModuleCallReply *reply) {
5526 return callReplyGetBool(reply);
5527}
5528
5529/* Return the 'idx'-th nested call reply element of a set reply, or NULL
5530 * if the reply type is wrong or the index is out of range. */
5531RedisModuleCallReply *RM_CallReplySetElement(RedisModuleCallReply *reply, size_t idx) {
5532 return callReplyGetSetElement(reply, idx);
5533}
5534
5535/* Retrieve the 'idx'-th key and value of a map reply.
5536 *
5537 * Returns:
5538 * - REDISMODULE_OK on success.
5539 * - REDISMODULE_ERR if idx out of range or if the reply type is wrong.
5540 *
5541 * The `key` and `value` arguments are used to return by reference, and may be
5542 * NULL if not required. */
5543int RM_CallReplyMapElement(RedisModuleCallReply *reply, size_t idx, RedisModuleCallReply **key, RedisModuleCallReply **val) {
5544 if (callReplyGetMapElement(reply, idx, key, val) == C_OK){
5545 return REDISMODULE_OK;
5546 }
5547 return REDISMODULE_ERR;
5548}
5549
5550/* Return the attribute of the given reply, or NULL if no attribute exists. */
5551RedisModuleCallReply *RM_CallReplyAttribute(RedisModuleCallReply *reply) {
5552 return callReplyGetAttribute(reply);
5553}
5554
5555/* Retrieve the 'idx'-th key and value of an attribute reply.
5556 *
5557 * Returns:
5558 * - REDISMODULE_OK on success.
5559 * - REDISMODULE_ERR if idx out of range or if the reply type is wrong.
5560 *
5561 * The `key` and `value` arguments are used to return by reference, and may be
5562 * NULL if not required. */
5563int RM_CallReplyAttributeElement(RedisModuleCallReply *reply, size_t idx, RedisModuleCallReply **key, RedisModuleCallReply **val) {
5564 if (callReplyGetAttributeElement(reply, idx, key, val) == C_OK){
5565 return REDISMODULE_OK;
5566 }
5567 return REDISMODULE_ERR;
5568}
5569
5570/* Return the pointer and length of a string or error reply. */
5571const char *RM_CallReplyStringPtr(RedisModuleCallReply *reply, size_t *len) {
5572 size_t private_len;
5573 if (!len) len = &private_len;
5574 return callReplyGetString(reply, len);
5575}
5576
5577/* Return a new string object from a call reply of type string, error or
5578 * integer. Otherwise (wrong reply type) return NULL. */
5579RedisModuleString *RM_CreateStringFromCallReply(RedisModuleCallReply *reply) {
5580 RedisModuleCtx* ctx = callReplyGetPrivateData(reply);
5581 size_t len;
5582 const char *str;
5583 switch(callReplyType(reply)) {
5584 case REDISMODULE_REPLY_STRING:
5585 case REDISMODULE_REPLY_ERROR:
5586 str = callReplyGetString(reply, &len);
5587 return RM_CreateString(ctx, str, len);
5588 case REDISMODULE_REPLY_INTEGER: {
5589 char buf[64];
5590 int len = ll2string(buf,sizeof(buf),callReplyGetLongLong(reply));
5591 return RM_CreateString(ctx ,buf,len);
5592 }
5593 default:
5594 return NULL;
5595 }
5596}
5597
5598/* Returns an array of robj pointers, by parsing the format specifier "fmt" as described for
5599 * the RM_Call(), RM_Replicate() and other module APIs. Populates *argcp with the number of
5600 * items and *argvlenp with the length of the allocated argv.
5601 *
5602 * The integer pointed by 'flags' is populated with flags according
5603 * to special modifiers in "fmt".
5604 *
5605 * "!" -> REDISMODULE_ARGV_REPLICATE
5606 * "A" -> REDISMODULE_ARGV_NO_AOF
5607 * "R" -> REDISMODULE_ARGV_NO_REPLICAS
5608 * "3" -> REDISMODULE_ARGV_RESP_3
5609 * "0" -> REDISMODULE_ARGV_RESP_AUTO
5610 * "C" -> REDISMODULE_ARGV_CHECK_ACL
5611 *
5612 * On error (format specifier error) NULL is returned and nothing is
5613 * allocated. On success the argument vector is returned. */
5614robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *argvlenp, int *flags, va_list ap) {
5615 int argc = 0, argv_size, j;
5616 robj **argv = NULL;
5617
5618 /* As a first guess to avoid useless reallocations, size argv to
5619 * hold one argument for each char specifier in 'fmt'. */
5620 argv_size = strlen(fmt)+1; /* +1 because of the command name. */
5621 argv = zrealloc(argv,sizeof(robj*)*argv_size);
5622
5623 /* Build the arguments vector based on the format specifier. */
5624 argv[0] = createStringObject(cmdname,strlen(cmdname));
5625 argc++;
5626
5627 /* Create the client and dispatch the command. */
5628 const char *p = fmt;
5629 while(*p) {
5630 if (*p == 'c') {
5631 char *cstr = va_arg(ap,char*);
5632 argv[argc++] = createStringObject(cstr,strlen(cstr));
5633 } else if (*p == 's') {
5634 robj *obj = va_arg(ap,void*);
5635 if (obj->refcount == OBJ_STATIC_REFCOUNT)
5636 obj = createStringObject(obj->ptr,sdslen(obj->ptr));
5637 else
5638 incrRefCount(obj);
5639 argv[argc++] = obj;
5640 } else if (*p == 'b') {
5641 char *buf = va_arg(ap,char*);
5642 size_t len = va_arg(ap,size_t);
5643 argv[argc++] = createStringObject(buf,len);
5644 } else if (*p == 'l') {
5645 long long ll = va_arg(ap,long long);
5646 argv[argc++] = createObject(OBJ_STRING,sdsfromlonglong(ll));
5647 } else if (*p == 'v') {
5648 /* A vector of strings */
5649 robj **v = va_arg(ap, void*);
5650 size_t vlen = va_arg(ap, size_t);
5651
5652 /* We need to grow argv to hold the vector's elements.
5653 * We resize by vector_len-1 elements, because we held
5654 * one element in argv for the vector already */
5655 argv_size += vlen-1;
5656 argv = zrealloc(argv,sizeof(robj*)*argv_size);
5657
5658 size_t i = 0;
5659 for (i = 0; i < vlen; i++) {
5660 incrRefCount(v[i]);
5661 argv[argc++] = v[i];
5662 }
5663 } else if (*p == '!') {
5664 if (flags) (*flags) |= REDISMODULE_ARGV_REPLICATE;
5665 } else if (*p == 'A') {
5666 if (flags) (*flags) |= REDISMODULE_ARGV_NO_AOF;
5667 } else if (*p == 'R') {
5668 if (flags) (*flags) |= REDISMODULE_ARGV_NO_REPLICAS;
5669 } else if (*p == '3') {
5670 if (flags) (*flags) |= REDISMODULE_ARGV_RESP_3;
5671 } else if (*p == '0') {
5672 if (flags) (*flags) |= REDISMODULE_ARGV_RESP_AUTO;
5673 } else if (*p == 'C') {
5674 if (flags) (*flags) |= REDISMODULE_ARGV_CHECK_ACL;
5675 } else if (*p == 'S') {
5676 if (flags) (*flags) |= REDISMODULE_ARGV_SCRIPT_MODE;
5677 } else if (*p == 'W') {
5678 if (flags) (*flags) |= REDISMODULE_ARGV_NO_WRITES;
5679 } else if (*p == 'M') {
5680 if (flags) (*flags) |= REDISMODULE_ARGV_RESPECT_DENY_OOM;
5681 } else if (*p == 'E') {
5682 if (flags) (*flags) |= REDISMODULE_ARGV_CALL_REPLIES_AS_ERRORS;
5683 } else {
5684 goto fmterr;
5685 }
5686 p++;
5687 }
5688 if (argcp) *argcp = argc;
5689 if (argvlenp) *argvlenp = argv_size;
5690 return argv;
5691
5692fmterr:
5693 for (j = 0; j < argc; j++)
5694 decrRefCount(argv[j]);
5695 zfree(argv);
5696 return NULL;
5697}
5698
5699/* Exported API to call any Redis command from modules.
5700 *
5701 * * **cmdname**: The Redis command to call.
5702 * * **fmt**: A format specifier string for the command's arguments. Each
5703 * of the arguments should be specified by a valid type specification. The
5704 * format specifier can also contain the modifiers `!`, `A`, `3` and `R` which
5705 * don't have a corresponding argument.
5706 *
5707 * * `b` -- The argument is a buffer and is immediately followed by another
5708 * argument that is the buffer's length.
5709 * * `c` -- The argument is a pointer to a plain C string (null-terminated).
5710 * * `l` -- The argument is a `long long` integer.
5711 * * `s` -- The argument is a RedisModuleString.
5712 * * `v` -- The argument(s) is a vector of RedisModuleString.
5713 * * `!` -- Sends the Redis command and its arguments to replicas and AOF.
5714 * * `A` -- Suppress AOF propagation, send only to replicas (requires `!`).
5715 * * `R` -- Suppress replicas propagation, send only to AOF (requires `!`).
5716 * * `3` -- Return a RESP3 reply. This will change the command reply.
5717 * e.g., HGETALL returns a map instead of a flat array.
5718 * * `0` -- Return the reply in auto mode, i.e. the reply format will be the
5719 * same as the client attached to the given RedisModuleCtx. This will
5720 * probably used when you want to pass the reply directly to the client.
5721 * * `C` -- Check if command can be executed according to ACL rules.
5722 * * `S` -- Run the command in a script mode, this means that it will raise
5723 * an error if a command which are not allowed inside a script
5724 * (flagged with the `deny-script` flag) is invoked (like SHUTDOWN).
5725 * In addition, on script mode, write commands are not allowed if there are
5726 * not enough good replicas (as configured with `min-replicas-to-write`)
5727 * or when the server is unable to persist to the disk.
5728 * * `W` -- Do not allow to run any write command (flagged with the `write` flag).
5729 * * `M` -- Do not allow `deny-oom` flagged commands when over the memory limit.
5730 * * `E` -- Return error as RedisModuleCallReply. If there is an error before
5731 * invoking the command, the error is returned using errno mechanism.
5732 * This flag allows to get the error also as an error CallReply with
5733 * relevant error message.
5734 * * **...**: The actual arguments to the Redis command.
5735 *
5736 * On success a RedisModuleCallReply object is returned, otherwise
5737 * NULL is returned and errno is set to the following values:
5738 *
5739 * * EBADF: wrong format specifier.
5740 * * EINVAL: wrong command arity.
5741 * * ENOENT: command does not exist.
5742 * * EPERM: operation in Cluster instance with key in non local slot.
5743 * * EROFS: operation in Cluster instance when a write command is sent
5744 * in a readonly state.
5745 * * ENETDOWN: operation in Cluster instance when cluster is down.
5746 * * ENOTSUP: No ACL user for the specified module context
5747 * * EACCES: Command cannot be executed, according to ACL rules
5748 * * ENOSPC: Write or deny-oom command is not allowed
5749 * * ESPIPE: Command not allowed on script mode
5750 *
5751 * Example code fragment:
5752 *
5753 * reply = RedisModule_Call(ctx,"INCRBY","sc",argv[1],"10");
5754 * if (RedisModule_CallReplyType(reply) == REDISMODULE_REPLY_INTEGER) {
5755 * long long myval = RedisModule_CallReplyInteger(reply);
5756 * // Do something with myval.
5757 * }
5758 *
5759 * This API is documented here: https://redis.io/topics/modules-intro
5760 */
5761RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
5762 struct redisCommand *cmd;
5763 client *c = NULL;
5764 robj **argv = NULL;
5765 int argc = 0, argv_len = 0, flags = 0;
5766 va_list ap;
5767 RedisModuleCallReply *reply = NULL;
5768 int replicate = 0; /* Replicate this command? */
5769 int error_as_call_replies = 0; /* return errors as RedisModuleCallReply object */
5770
5771 /* Handle arguments. */
5772 va_start(ap, fmt);
5773 argv = moduleCreateArgvFromUserFormat(cmdname,fmt,&argc,&argv_len,&flags,ap);
5774 replicate = flags & REDISMODULE_ARGV_REPLICATE;
5775 error_as_call_replies = flags & REDISMODULE_ARGV_CALL_REPLIES_AS_ERRORS;
5776 va_end(ap);
5777
5778 c = moduleAllocTempClient();
5779
5780 /* We do not want to allow block, the module do not expect it */
5781 c->flags |= CLIENT_DENY_BLOCKING;
5782 c->db = ctx->client->db;
5783 c->argv = argv;
5784 c->argc = argc;
5785 c->argv_len = argv_len;
5786 c->resp = 2;
5787 if (flags & REDISMODULE_ARGV_RESP_3) {
5788 c->resp = 3;
5789 } else if (flags & REDISMODULE_ARGV_RESP_AUTO) {
5790 /* Auto mode means to take the same protocol as the ctx client. */
5791 c->resp = ctx->client->resp;
5792 }
5793 if (ctx->module) ctx->module->in_call++;
5794
5795 /* We handle the above format error only when the client is setup so that
5796 * we can free it normally. */
5797 if (argv == NULL) {
5798 /* We do not return a call reply here this is an error that should only
5799 * be catch by the module indicating wrong fmt was given, the module should
5800 * handle this error and decide how to continue. It is not an error that
5801 * should be propagated to the user. */
5802 errno = EBADF;
5803 goto cleanup;
5804 }
5805
5806 /* Call command filters */
5807 moduleCallCommandFilters(c);
5808
5809 /* Lookup command now, after filters had a chance to make modifications
5810 * if necessary.
5811 */
5812 cmd = c->cmd = c->lastcmd = c->realcmd = lookupCommand(c->argv,c->argc);
5813 sds err;
5814 if (!commandCheckExistence(c, error_as_call_replies? &err : NULL)) {
5815 errno = ENOENT;
5816 if (error_as_call_replies)
5817 reply = callReplyCreateError(err, ctx);
5818 goto cleanup;
5819 }
5820 if (!commandCheckArity(c, error_as_call_replies? &err : NULL)) {
5821 errno = EINVAL;
5822 if (error_as_call_replies)
5823 reply = callReplyCreateError(err, ctx);
5824 goto cleanup;
5825 }
5826
5827 if (flags & REDISMODULE_ARGV_SCRIPT_MODE) {
5828 /* Basically on script mode we want to only allow commands that can
5829 * be executed on scripts (CMD_NOSCRIPT is not set on the command flags) */
5830 if (cmd->flags & CMD_NOSCRIPT) {
5831 errno = ESPIPE;
5832 if (error_as_call_replies) {
5833 sds msg = sdscatfmt(sdsempty(), "command '%S' is not allowed on script mode", c->cmd->fullname);
5834 reply = callReplyCreateError(msg, ctx);
5835 }
5836 goto cleanup;
5837 }
5838 }
5839
5840 if (flags & REDISMODULE_ARGV_RESPECT_DENY_OOM) {
5841 if (cmd->flags & CMD_DENYOOM) {
5842 int oom_state;
5843 if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) {
5844 /* On background thread we can not count on server.pre_command_oom_state.
5845 * Because it is only set on the main thread, in such case we will check
5846 * the actual memory usage. */
5847 oom_state = (getMaxmemoryState(NULL,NULL,NULL,NULL) == C_ERR);
5848 } else {
5849 oom_state = server.pre_command_oom_state;
5850 }
5851 if (oom_state) {
5852 errno = ENOSPC;
5853 if (error_as_call_replies) {
5854 sds msg = sdsdup(shared.oomerr->ptr);
5855 reply = callReplyCreateError(msg, ctx);
5856 }
5857 goto cleanup;
5858 }
5859 }
5860 }
5861
5862 if (flags & REDISMODULE_ARGV_NO_WRITES) {
5863 if (cmd->flags & CMD_WRITE) {
5864 errno = ENOSPC;
5865 if (error_as_call_replies) {
5866 sds msg = sdscatfmt(sdsempty(), "Write command '%S' was "
5867 "called while write is not allowed.", c->cmd->fullname);
5868 reply = callReplyCreateError(msg, ctx);
5869 }
5870 goto cleanup;
5871 }
5872 }
5873
5874 /* Script mode tests */
5875 if (flags & REDISMODULE_ARGV_SCRIPT_MODE) {
5876 if (cmd->flags & CMD_WRITE) {
5877 /* on script mode, if a command is a write command,
5878 * We will not run it if we encounter disk error
5879 * or we do not have enough replicas */
5880
5881 if (!checkGoodReplicasStatus()) {
5882 errno = ESPIPE;
5883 if (error_as_call_replies) {
5884 sds msg = sdsdup(shared.noreplicaserr->ptr);
5885 reply = callReplyCreateError(msg, ctx);
5886 }
5887 goto cleanup;
5888 }
5889
5890 int deny_write_type = writeCommandsDeniedByDiskError();
5891 int obey_client = (server.current_client && mustObeyClient(server.current_client));
5892
5893 if (deny_write_type != DISK_ERROR_TYPE_NONE && !obey_client) {
5894 errno = ESPIPE;
5895 if (error_as_call_replies) {
5896 sds msg = writeCommandsGetDiskErrorMessage(deny_write_type);
5897 reply = callReplyCreateError(msg, ctx);
5898 }
5899 goto cleanup;
5900 }
5901
5902 if (server.masterhost && server.repl_slave_ro && !obey_client) {
5903 errno = ESPIPE;
5904 if (error_as_call_replies) {
5905 sds msg = sdsdup(shared.roslaveerr->ptr);
5906 reply = callReplyCreateError(msg, ctx);
5907 }
5908 goto cleanup;
5909 }
5910 }
5911
5912 if (server.masterhost && server.repl_state != REPL_STATE_CONNECTED &&
5913 server.repl_serve_stale_data == 0 && !(cmd->flags & CMD_STALE)) {
5914 errno = ESPIPE;
5915 if (error_as_call_replies) {
5916 sds msg = sdsdup(shared.masterdownerr->ptr);
5917 reply = callReplyCreateError(msg, ctx);
5918 }
5919 goto cleanup;
5920 }
5921 }
5922
5923 /* Check if the user can run this command according to the current
5924 * ACLs. */
5925 if (flags & REDISMODULE_ARGV_CHECK_ACL) {
5926 int acl_errpos;
5927 int acl_retval;
5928
5929 if (ctx->client->user == NULL) {
5930 errno = ENOTSUP;
5931 if (error_as_call_replies) {
5932 sds msg = sdsnew("acl verification failed, context is not attached to a client.");
5933 reply = callReplyCreateError(msg, ctx);
5934 }
5935 goto cleanup;
5936 }
5937 acl_retval = ACLCheckAllUserCommandPerm(ctx->client->user,c->cmd,c->argv,c->argc,&acl_errpos);
5938 if (acl_retval != ACL_OK) {
5939 sds object = (acl_retval == ACL_DENIED_CMD) ? sdsdup(c->cmd->fullname) : sdsdup(c->argv[acl_errpos]->ptr);
5940 addACLLogEntry(ctx->client, acl_retval, ACL_LOG_CTX_MODULE, -1, ctx->client->user->name, object);
5941 if (error_as_call_replies) {
5942 sds msg = sdscatfmt(sdsempty(), "acl verification failed, %s.", getAclErrorMessage(acl_retval));
5943 reply = callReplyCreateError(msg, ctx);
5944 }
5945 errno = EACCES;
5946 goto cleanup;
5947 }
5948 }
5949
5950 /* If this is a Redis Cluster node, we need to make sure the module is not
5951 * trying to access non-local keys, with the exception of commands
5952 * received from our master. */
5953 if (server.cluster_enabled && !mustObeyClient(ctx->client)) {
5954 int error_code;
5955 /* Duplicate relevant flags in the module client. */
5956 c->flags &= ~(CLIENT_READONLY|CLIENT_ASKING);
5957 c->flags |= ctx->client->flags & (CLIENT_READONLY|CLIENT_ASKING);
5958 if (getNodeByQuery(c,c->cmd,c->argv,c->argc,NULL,&error_code) !=
5959 server.cluster->myself)
5960 {
5961 sds msg = NULL;
5962 if (error_code == CLUSTER_REDIR_DOWN_RO_STATE) {
5963 if (error_as_call_replies) {
5964 msg = sdscatfmt(sdsempty(), "Can not execute a write command '%S' while the cluster is down and readonly", c->cmd->fullname);
5965 }
5966 errno = EROFS;
5967 } else if (error_code == CLUSTER_REDIR_DOWN_STATE) {
5968 if (error_as_call_replies) {
5969 msg = sdscatfmt(sdsempty(), "Can not execute a command '%S' while the cluster is down", c->cmd->fullname);
5970 }
5971 errno = ENETDOWN;
5972 } else {
5973 if (error_as_call_replies) {
5974 msg = sdsnew("Attempted to access a non local key in a cluster node");
5975 }
5976 errno = EPERM;
5977 }
5978 if (msg) {
5979 reply = callReplyCreateError(msg, ctx);
5980 }
5981 goto cleanup;
5982 }
5983 }
5984
5985 /* We need to use a global replication_allowed flag in order to prevent
5986 * replication of nested RM_Calls. Example:
5987 * 1. module1.foo does RM_Call of module2.bar without replication (i.e. no '!')
5988 * 2. module2.bar internally calls RM_Call of INCR with '!'
5989 * 3. at the end of module1.foo we call RM_ReplicateVerbatim
5990 * We want the replica/AOF to see only module1.foo and not the INCR from module2.bar */
5991 int prev_replication_allowed = server.replication_allowed;
5992 server.replication_allowed = replicate && server.replication_allowed;
5993
5994 /* Run the command */
5995 int call_flags = CMD_CALL_SLOWLOG | CMD_CALL_STATS | CMD_CALL_FROM_MODULE;
5996 if (replicate) {
5997 if (!(flags & REDISMODULE_ARGV_NO_AOF))
5998 call_flags |= CMD_CALL_PROPAGATE_AOF;
5999 if (!(flags & REDISMODULE_ARGV_NO_REPLICAS))
6000 call_flags |= CMD_CALL_PROPAGATE_REPL;
6001 }
6002 call(c,call_flags);
6003 server.replication_allowed = prev_replication_allowed;
6004
6005 serverAssert((c->flags & CLIENT_BLOCKED) == 0);
6006
6007 /* Convert the result of the Redis command into a module reply. */
6008 sds proto = sdsnewlen(c->buf,c->bufpos);
6009 c->bufpos = 0;
6010 while(listLength(c->reply)) {
6011 clientReplyBlock *o = listNodeValue(listFirst(c->reply));
6012
6013 proto = sdscatlen(proto,o->buf,o->used);
6014 listDelNode(c->reply,listFirst(c->reply));
6015 }
6016 reply = callReplyCreate(proto, c->deferred_reply_errors, ctx);
6017 c->deferred_reply_errors = NULL; /* now the responsibility of the reply object. */
6018
6019cleanup:
6020 if (reply) autoMemoryAdd(ctx,REDISMODULE_AM_REPLY,reply);
6021 if (ctx->module) ctx->module->in_call--;
6022 moduleReleaseTempClient(c);
6023 return reply;
6024}
6025
6026/* Return a pointer, and a length, to the protocol returned by the command
6027 * that returned the reply object. */
6028const char *RM_CallReplyProto(RedisModuleCallReply *reply, size_t *len) {
6029 return callReplyGetProto(reply, len);
6030}
6031
6032/* --------------------------------------------------------------------------
6033 * ## Modules data types
6034 *
6035 * When String DMA or using existing data structures is not enough, it is
6036 * possible to create new data types from scratch and export them to
6037 * Redis. The module must provide a set of callbacks for handling the
6038 * new values exported (for example in order to provide RDB saving/loading,
6039 * AOF rewrite, and so forth). In this section we define this API.
6040 * -------------------------------------------------------------------------- */
6041
6042/* Turn a 9 chars name in the specified charset and a 10 bit encver into
6043 * a single 64 bit unsigned integer that represents this exact module name
6044 * and version. This final number is called a "type ID" and is used when
6045 * writing module exported values to RDB files, in order to re-associate the
6046 * value to the right module to load them during RDB loading.
6047 *
6048 * If the string is not of the right length or the charset is wrong, or
6049 * if encver is outside the unsigned 10 bit integer range, 0 is returned,
6050 * otherwise the function returns the right type ID.
6051 *
6052 * The resulting 64 bit integer is composed as follows:
6053 *
6054 * (high order bits) 6|6|6|6|6|6|6|6|6|10 (low order bits)
6055 *
6056 * The first 6 bits value is the first character, name[0], while the last
6057 * 6 bits value, immediately before the 10 bits integer, is name[8].
6058 * The last 10 bits are the encoding version.
6059 *
6060 * Note that a name and encver combo of "AAAAAAAAA" and 0, will produce
6061 * zero as return value, that is the same we use to signal errors, thus
6062 * this combination is invalid, and also useless since type names should
6063 * try to be vary to avoid collisions. */
6064
6065const char *ModuleTypeNameCharSet =
6066 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
6067 "abcdefghijklmnopqrstuvwxyz"
6068 "0123456789-_";
6069
6070uint64_t moduleTypeEncodeId(const char *name, int encver) {
6071 /* We use 64 symbols so that we can map each character into 6 bits
6072 * of the final output. */
6073 const char *cset = ModuleTypeNameCharSet;
6074 if (strlen(name) != 9) return 0;
6075 if (encver < 0 || encver > 1023) return 0;
6076
6077 uint64_t id = 0;
6078 for (int j = 0; j < 9; j++) {
6079 char *p = strchr(cset,name[j]);
6080 if (!p) return 0;
6081 unsigned long pos = p-cset;
6082 id = (id << 6) | pos;
6083 }
6084 id = (id << 10) | encver;
6085 return id;
6086}
6087
6088/* Search, in the list of exported data types of all the modules registered,
6089 * a type with the same name as the one given. Returns the moduleType
6090 * structure pointer if such a module is found, or NULL otherwise. */
6091moduleType *moduleTypeLookupModuleByName(const char *name) {
6092 dictIterator *di = dictGetIterator(modules);
6093 dictEntry *de;
6094
6095 while ((de = dictNext(di)) != NULL) {
6096 struct RedisModule *module = dictGetVal(de);
6097 listIter li;
6098 listNode *ln;
6099
6100 listRewind(module->types,&li);
6101 while((ln = listNext(&li))) {
6102 moduleType *mt = ln->value;
6103 if (memcmp(name,mt->name,sizeof(mt->name)) == 0) {
6104 dictReleaseIterator(di);
6105 return mt;
6106 }
6107 }
6108 }
6109 dictReleaseIterator(di);
6110 return NULL;
6111}
6112
6113/* Lookup a module by ID, with caching. This function is used during RDB
6114 * loading. Modules exporting data types should never be able to unload, so
6115 * our cache does not need to expire. */
6116#define MODULE_LOOKUP_CACHE_SIZE 3
6117
6118moduleType *moduleTypeLookupModuleByID(uint64_t id) {
6119 static struct {
6120 uint64_t id;
6121 moduleType *mt;
6122 } cache[MODULE_LOOKUP_CACHE_SIZE];
6123
6124 /* Search in cache to start. */
6125 int j;
6126 for (j = 0; j < MODULE_LOOKUP_CACHE_SIZE && cache[j].mt != NULL; j++)
6127 if (cache[j].id == id) return cache[j].mt;
6128
6129 /* Slow module by module lookup. */
6130 moduleType *mt = NULL;
6131 dictIterator *di = dictGetIterator(modules);
6132 dictEntry *de;
6133
6134 while ((de = dictNext(di)) != NULL && mt == NULL) {
6135 struct RedisModule *module = dictGetVal(de);
6136 listIter li;
6137 listNode *ln;
6138
6139 listRewind(module->types,&li);
6140 while((ln = listNext(&li))) {
6141 moduleType *this_mt = ln->value;
6142 /* Compare only the 54 bit module identifier and not the
6143 * encoding version. */
6144 if (this_mt->id >> 10 == id >> 10) {
6145 mt = this_mt;
6146 break;
6147 }
6148 }
6149 }
6150 dictReleaseIterator(di);
6151
6152 /* Add to cache if possible. */
6153 if (mt && j < MODULE_LOOKUP_CACHE_SIZE) {
6154 cache[j].id = id;
6155 cache[j].mt = mt;
6156 }
6157 return mt;
6158}
6159
6160/* Turn an (unresolved) module ID into a type name, to show the user an
6161 * error when RDB files contain module data we can't load.
6162 * The buffer pointed by 'name' must be 10 bytes at least. The function will
6163 * fill it with a null terminated module name. */
6164void moduleTypeNameByID(char *name, uint64_t moduleid) {
6165 const char *cset = ModuleTypeNameCharSet;
6166
6167 name[9] = '\0';
6168 char *p = name+8;
6169 moduleid >>= 10;
6170 for (int j = 0; j < 9; j++) {
6171 *p-- = cset[moduleid & 63];
6172 moduleid >>= 6;
6173 }
6174}
6175
6176/* Return the name of the module that owns the specified moduleType. */
6177const char *moduleTypeModuleName(moduleType *mt) {
6178 if (!mt || !mt->module) return NULL;
6179 return mt->module->name;
6180}
6181
6182/* Return the module name from a module command */
6183const char *moduleNameFromCommand(struct redisCommand *cmd) {
6184 serverAssert(cmd->proc == RedisModuleCommandDispatcher);
6185
6186 RedisModuleCommand *cp = cmd->module_cmd;
6187 return cp->module->name;
6188}
6189
6190/* Create a copy of a module type value using the copy callback. If failed
6191 * or not supported, produce an error reply and return NULL.
6192 */
6193robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj *value) {
6194 moduleValue *mv = value->ptr;
6195 moduleType *mt = mv->type;
6196 if (!mt->copy && !mt->copy2) {
6197 addReplyError(c, "not supported for this module key");
6198 return NULL;
6199 }
6200 void *newval = NULL;
6201 if (mt->copy2 != NULL) {
6202 RedisModuleKeyOptCtx ctx = {fromkey, tokey, c->db->id, todb};
6203 newval = mt->copy2(&ctx, mv->value);
6204 } else {
6205 newval = mt->copy(fromkey, tokey, mv->value);
6206 }
6207
6208 if (!newval) {
6209 addReplyError(c, "module key failed to copy");
6210 return NULL;
6211 }
6212 return createModuleObject(mt, newval);
6213}
6214
6215/* Register a new data type exported by the module. The parameters are the
6216 * following. Please for in depth documentation check the modules API
6217 * documentation, especially https://redis.io/topics/modules-native-types.
6218 *
6219 * * **name**: A 9 characters data type name that MUST be unique in the Redis
6220 * Modules ecosystem. Be creative... and there will be no collisions. Use
6221 * the charset A-Z a-z 9-0, plus the two "-_" characters. A good
6222 * idea is to use, for example `<typename>-<vendor>`. For example
6223 * "tree-AntZ" may mean "Tree data structure by @antirez". To use both
6224 * lower case and upper case letters helps in order to prevent collisions.
6225 * * **encver**: Encoding version, which is, the version of the serialization
6226 * that a module used in order to persist data. As long as the "name"
6227 * matches, the RDB loading will be dispatched to the type callbacks
6228 * whatever 'encver' is used, however the module can understand if
6229 * the encoding it must load are of an older version of the module.
6230 * For example the module "tree-AntZ" initially used encver=0. Later
6231 * after an upgrade, it started to serialize data in a different format
6232 * and to register the type with encver=1. However this module may
6233 * still load old data produced by an older version if the rdb_load
6234 * callback is able to check the encver value and act accordingly.
6235 * The encver must be a positive value between 0 and 1023.
6236 *
6237 * * **typemethods_ptr** is a pointer to a RedisModuleTypeMethods structure
6238 * that should be populated with the methods callbacks and structure
6239 * version, like in the following example:
6240 *
6241 * RedisModuleTypeMethods tm = {
6242 * .version = REDISMODULE_TYPE_METHOD_VERSION,
6243 * .rdb_load = myType_RDBLoadCallBack,
6244 * .rdb_save = myType_RDBSaveCallBack,
6245 * .aof_rewrite = myType_AOFRewriteCallBack,
6246 * .free = myType_FreeCallBack,
6247 *
6248 * // Optional fields
6249 * .digest = myType_DigestCallBack,
6250 * .mem_usage = myType_MemUsageCallBack,
6251 * .aux_load = myType_AuxRDBLoadCallBack,
6252 * .aux_save = myType_AuxRDBSaveCallBack,
6253 * .free_effort = myType_FreeEffortCallBack,
6254 * .unlink = myType_UnlinkCallBack,
6255 * .copy = myType_CopyCallback,
6256 * .defrag = myType_DefragCallback
6257 *
6258 * // Enhanced optional fields
6259 * .mem_usage2 = myType_MemUsageCallBack2,
6260 * .free_effort2 = myType_FreeEffortCallBack2,
6261 * .unlink2 = myType_UnlinkCallBack2,
6262 * .copy2 = myType_CopyCallback2,
6263 * }
6264 *
6265 * * **rdb_load**: A callback function pointer that loads data from RDB files.
6266 * * **rdb_save**: A callback function pointer that saves data to RDB files.
6267 * * **aof_rewrite**: A callback function pointer that rewrites data as commands.
6268 * * **digest**: A callback function pointer that is used for `DEBUG DIGEST`.
6269 * * **free**: A callback function pointer that can free a type value.
6270 * * **aux_save**: A callback function pointer that saves out of keyspace data to RDB files.
6271 * 'when' argument is either REDISMODULE_AUX_BEFORE_RDB or REDISMODULE_AUX_AFTER_RDB.
6272 * * **aux_load**: A callback function pointer that loads out of keyspace data from RDB files.
6273 * Similar to aux_save, returns REDISMODULE_OK on success, and ERR otherwise.
6274 * * **free_effort**: A callback function pointer that used to determine whether the module's
6275 * memory needs to be lazy reclaimed. The module should return the complexity involved by
6276 * freeing the value. for example: how many pointers are gonna be freed. Note that if it
6277 * returns 0, we'll always do an async free.
6278 * * **unlink**: A callback function pointer that used to notifies the module that the key has
6279 * been removed from the DB by redis, and may soon be freed by a background thread. Note that
6280 * it won't be called on FLUSHALL/FLUSHDB (both sync and async), and the module can use the
6281 * RedisModuleEvent_FlushDB to hook into that.
6282 * * **copy**: A callback function pointer that is used to make a copy of the specified key.
6283 * The module is expected to perform a deep copy of the specified value and return it.
6284 * In addition, hints about the names of the source and destination keys is provided.
6285 * A NULL return value is considered an error and the copy operation fails.
6286 * Note: if the target key exists and is being overwritten, the copy callback will be
6287 * called first, followed by a free callback to the value that is being replaced.
6288 *
6289 * * **defrag**: A callback function pointer that is used to request the module to defrag
6290 * a key. The module should then iterate pointers and call the relevant RM_Defrag*()
6291 * functions to defragment pointers or complex types. The module should continue
6292 * iterating as long as RM_DefragShouldStop() returns a zero value, and return a
6293 * zero value if finished or non-zero value if more work is left to be done. If more work
6294 * needs to be done, RM_DefragCursorSet() and RM_DefragCursorGet() can be used to track
6295 * this work across different calls.
6296 * Normally, the defrag mechanism invokes the callback without a time limit, so
6297 * RM_DefragShouldStop() always returns zero. The "late defrag" mechanism which has
6298 * a time limit and provides cursor support is used only for keys that are determined
6299 * to have significant internal complexity. To determine this, the defrag mechanism
6300 * uses the free_effort callback and the 'active-defrag-max-scan-fields' config directive.
6301 * NOTE: The value is passed as a `void**` and the function is expected to update the
6302 * pointer if the top-level value pointer is defragmented and consequently changes.
6303 *
6304 * * **mem_usage2**: Similar to `mem_usage`, but provides the `RedisModuleKeyOptCtx` parameter
6305 * so that meta information such as key name and db id can be obtained, and
6306 * the `sample_size` for size estimation (see MEMORY USAGE command).
6307 * * **free_effort2**: Similar to `free_effort`, but provides the `RedisModuleKeyOptCtx` parameter
6308 * so that meta information such as key name and db id can be obtained.
6309 * * **unlink2**: Similar to `unlink`, but provides the `RedisModuleKeyOptCtx` parameter
6310 * so that meta information such as key name and db id can be obtained.
6311 * * **copy2**: Similar to `copy`, but provides the `RedisModuleKeyOptCtx` parameter
6312 * so that meta information such as key names and db ids can be obtained.
6313 *
6314 * Note: the module name "AAAAAAAAA" is reserved and produces an error, it
6315 * happens to be pretty lame as well.
6316 *
6317 * If there is already a module registering a type with the same name,
6318 * and if the module name or encver is invalid, NULL is returned.
6319 * Otherwise the new type is registered into Redis, and a reference of
6320 * type RedisModuleType is returned: the caller of the function should store
6321 * this reference into a global variable to make future use of it in the
6322 * modules type API, since a single module may register multiple types.
6323 * Example code fragment:
6324 *
6325 * static RedisModuleType *BalancedTreeType;
6326 *
6327 * int RedisModule_OnLoad(RedisModuleCtx *ctx) {
6328 * // some code here ...
6329 * BalancedTreeType = RM_CreateDataType(...);
6330 * }
6331 */
6332moduleType *RM_CreateDataType(RedisModuleCtx *ctx, const char *name, int encver, void *typemethods_ptr) {
6333 uint64_t id = moduleTypeEncodeId(name,encver);
6334 if (id == 0) return NULL;
6335 if (moduleTypeLookupModuleByName(name) != NULL) return NULL;
6336
6337 long typemethods_version = ((long*)typemethods_ptr)[0];
6338 if (typemethods_version == 0) return NULL;
6339
6340 struct typemethods {
6341 uint64_t version;
6342 moduleTypeLoadFunc rdb_load;
6343 moduleTypeSaveFunc rdb_save;
6344 moduleTypeRewriteFunc aof_rewrite;
6345 moduleTypeMemUsageFunc mem_usage;
6346 moduleTypeDigestFunc digest;
6347 moduleTypeFreeFunc free;
6348 struct {
6349 moduleTypeAuxLoadFunc aux_load;
6350 moduleTypeAuxSaveFunc aux_save;
6351 int aux_save_triggers;
6352 } v2;
6353 struct {
6354 moduleTypeFreeEffortFunc free_effort;
6355 moduleTypeUnlinkFunc unlink;
6356 moduleTypeCopyFunc copy;
6357 moduleTypeDefragFunc defrag;
6358 } v3;
6359 struct {
6360 moduleTypeMemUsageFunc2 mem_usage2;
6361 moduleTypeFreeEffortFunc2 free_effort2;
6362 moduleTypeUnlinkFunc2 unlink2;
6363 moduleTypeCopyFunc2 copy2;
6364 } v4;
6365 } *tms = (struct typemethods*) typemethods_ptr;
6366
6367 moduleType *mt = zcalloc(sizeof(*mt));
6368 mt->id = id;
6369 mt->module = ctx->module;
6370 mt->rdb_load = tms->rdb_load;
6371 mt->rdb_save = tms->rdb_save;
6372 mt->aof_rewrite = tms->aof_rewrite;
6373 mt->mem_usage = tms->mem_usage;
6374 mt->digest = tms->digest;
6375 mt->free = tms->free;
6376 if (tms->version >= 2) {
6377 mt->aux_load = tms->v2.aux_load;
6378 mt->aux_save = tms->v2.aux_save;
6379 mt->aux_save_triggers = tms->v2.aux_save_triggers;
6380 }
6381 if (tms->version >= 3) {
6382 mt->free_effort = tms->v3.free_effort;
6383 mt->unlink = tms->v3.unlink;
6384 mt->copy = tms->v3.copy;
6385 mt->defrag = tms->v3.defrag;
6386 }
6387 if (tms->version >= 4) {
6388 mt->mem_usage2 = tms->v4.mem_usage2;
6389 mt->unlink2 = tms->v4.unlink2;
6390 mt->free_effort2 = tms->v4.free_effort2;
6391 mt->copy2 = tms->v4.copy2;
6392 }
6393 memcpy(mt->name,name,sizeof(mt->name));
6394 listAddNodeTail(ctx->module->types,mt);
6395 return mt;
6396}
6397
6398/* If the key is open for writing, set the specified module type object
6399 * as the value of the key, deleting the old value if any.
6400 * On success REDISMODULE_OK is returned. If the key is not open for
6401 * writing or there is an active iterator, REDISMODULE_ERR is returned. */
6402int RM_ModuleTypeSetValue(RedisModuleKey *key, moduleType *mt, void *value) {
6403 if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR;
6404 RM_DeleteKey(key);
6405 robj *o = createModuleObject(mt,value);
6406 setKey(key->ctx->client,key->db,key->key,o,SETKEY_NO_SIGNAL);
6407 decrRefCount(o);
6408 key->value = o;
6409 return REDISMODULE_OK;
6410}
6411
6412/* Assuming RedisModule_KeyType() returned REDISMODULE_KEYTYPE_MODULE on
6413 * the key, returns the module type pointer of the value stored at key.
6414 *
6415 * If the key is NULL, is not associated with a module type, or is empty,
6416 * then NULL is returned instead. */
6417moduleType *RM_ModuleTypeGetType(RedisModuleKey *key) {
6418 if (key == NULL ||
6419 key->value == NULL ||
6420 RM_KeyType(key) != REDISMODULE_KEYTYPE_MODULE) return NULL;
6421 moduleValue *mv = key->value->ptr;
6422 return mv->type;
6423}
6424
6425/* Assuming RedisModule_KeyType() returned REDISMODULE_KEYTYPE_MODULE on
6426 * the key, returns the module type low-level value stored at key, as
6427 * it was set by the user via RedisModule_ModuleTypeSetValue().
6428 *
6429 * If the key is NULL, is not associated with a module type, or is empty,
6430 * then NULL is returned instead. */
6431void *RM_ModuleTypeGetValue(RedisModuleKey *key) {
6432 if (key == NULL ||
6433 key->value == NULL ||
6434 RM_KeyType(key) != REDISMODULE_KEYTYPE_MODULE) return NULL;
6435 moduleValue *mv = key->value->ptr;
6436 return mv->value;
6437}
6438
6439/* --------------------------------------------------------------------------
6440 * ## RDB loading and saving functions
6441 * -------------------------------------------------------------------------- */
6442
6443/* Called when there is a load error in the context of a module. On some
6444 * modules this cannot be recovered, but if the module declared capability
6445 * to handle errors, we'll raise a flag rather than exiting. */
6446void moduleRDBLoadError(RedisModuleIO *io) {
6447 if (io->type->module->options & REDISMODULE_OPTIONS_HANDLE_IO_ERRORS) {
6448 io->error = 1;
6449 return;
6450 }
6451 serverPanic(
6452 "Error loading data from RDB (short read or EOF). "
6453 "Read performed by module '%s' about type '%s' "
6454 "after reading '%llu' bytes of a value "
6455 "for key named: '%s'.",
6456 io->type->module->name,
6457 io->type->name,
6458 (unsigned long long)io->bytes,
6459 io->key? (char*)io->key->ptr: "(null)");
6460}
6461
6462/* Returns 0 if there's at least one registered data type that did not declare
6463 * REDISMODULE_OPTIONS_HANDLE_IO_ERRORS, in which case diskless loading should
6464 * be avoided since it could cause data loss. */
6465int moduleAllDatatypesHandleErrors() {
6466 dictIterator *di = dictGetIterator(modules);
6467 dictEntry *de;
6468
6469 while ((de = dictNext(di)) != NULL) {
6470 struct RedisModule *module = dictGetVal(de);
6471 if (listLength(module->types) &&
6472 !(module->options & REDISMODULE_OPTIONS_HANDLE_IO_ERRORS))
6473 {
6474 dictReleaseIterator(di);
6475 return 0;
6476 }
6477 }
6478 dictReleaseIterator(di);
6479 return 1;
6480}
6481
6482/* Returns 0 if module did not declare REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD, in which case
6483 * diskless async loading should be avoided because module doesn't know there can be traffic during
6484 * database full resynchronization. */
6485int moduleAllModulesHandleReplAsyncLoad() {
6486 dictIterator *di = dictGetIterator(modules);
6487 dictEntry *de;
6488
6489 while ((de = dictNext(di)) != NULL) {
6490 struct RedisModule *module = dictGetVal(de);
6491 if (!(module->options & REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD)) {
6492 dictReleaseIterator(di);
6493 return 0;
6494 }
6495 }
6496 dictReleaseIterator(di);
6497 return 1;
6498}
6499
6500/* Returns true if any previous IO API failed.
6501 * for `Load*` APIs the REDISMODULE_OPTIONS_HANDLE_IO_ERRORS flag must be set with
6502 * RedisModule_SetModuleOptions first. */
6503int RM_IsIOError(RedisModuleIO *io) {
6504 return io->error;
6505}
6506
6507/* Save an unsigned 64 bit value into the RDB file. This function should only
6508 * be called in the context of the rdb_save method of modules implementing new
6509 * data types. */
6510void RM_SaveUnsigned(RedisModuleIO *io, uint64_t value) {
6511 if (io->error) return;
6512 /* Save opcode. */
6513 int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_UINT);
6514 if (retval == -1) goto saveerr;
6515 io->bytes += retval;
6516 /* Save value. */
6517 retval = rdbSaveLen(io->rio, value);
6518 if (retval == -1) goto saveerr;
6519 io->bytes += retval;
6520 return;
6521
6522saveerr:
6523 io->error = 1;
6524}
6525
6526/* Load an unsigned 64 bit value from the RDB file. This function should only
6527 * be called in the context of the `rdb_load` method of modules implementing
6528 * new data types. */
6529uint64_t RM_LoadUnsigned(RedisModuleIO *io) {
6530 if (io->error) return 0;
6531 if (io->ver == 2) {
6532 uint64_t opcode = rdbLoadLen(io->rio,NULL);
6533 if (opcode != RDB_MODULE_OPCODE_UINT) goto loaderr;
6534 }
6535 uint64_t value;
6536 int retval = rdbLoadLenByRef(io->rio, NULL, &value);
6537 if (retval == -1) goto loaderr;
6538 return value;
6539
6540loaderr:
6541 moduleRDBLoadError(io);
6542 return 0;
6543}
6544
6545/* Like RedisModule_SaveUnsigned() but for signed 64 bit values. */
6546void RM_SaveSigned(RedisModuleIO *io, int64_t value) {
6547 union {uint64_t u; int64_t i;} conv;
6548 conv.i = value;
6549 RM_SaveUnsigned(io,conv.u);
6550}
6551
6552/* Like RedisModule_LoadUnsigned() but for signed 64 bit values. */
6553int64_t RM_LoadSigned(RedisModuleIO *io) {
6554 union {uint64_t u; int64_t i;} conv;
6555 conv.u = RM_LoadUnsigned(io);
6556 return conv.i;
6557}
6558
6559/* In the context of the rdb_save method of a module type, saves a
6560 * string into the RDB file taking as input a RedisModuleString.
6561 *
6562 * The string can be later loaded with RedisModule_LoadString() or
6563 * other Load family functions expecting a serialized string inside
6564 * the RDB file. */
6565void RM_SaveString(RedisModuleIO *io, RedisModuleString *s) {
6566 if (io->error) return;
6567 /* Save opcode. */
6568 ssize_t retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING);
6569 if (retval == -1) goto saveerr;
6570 io->bytes += retval;
6571 /* Save value. */
6572 retval = rdbSaveStringObject(io->rio, s);
6573 if (retval == -1) goto saveerr;
6574 io->bytes += retval;
6575 return;
6576
6577saveerr:
6578 io->error = 1;
6579}
6580
6581/* Like RedisModule_SaveString() but takes a raw C pointer and length
6582 * as input. */
6583void RM_SaveStringBuffer(RedisModuleIO *io, const char *str, size_t len) {
6584 if (io->error) return;
6585 /* Save opcode. */
6586 ssize_t retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING);
6587 if (retval == -1) goto saveerr;
6588 io->bytes += retval;
6589 /* Save value. */
6590 retval = rdbSaveRawString(io->rio, (unsigned char*)str,len);
6591 if (retval == -1) goto saveerr;
6592 io->bytes += retval;
6593 return;
6594
6595saveerr:
6596 io->error = 1;
6597}
6598
6599/* Implements RM_LoadString() and RM_LoadStringBuffer() */
6600void *moduleLoadString(RedisModuleIO *io, int plain, size_t *lenptr) {
6601 if (io->error) return NULL;
6602 if (io->ver == 2) {
6603 uint64_t opcode = rdbLoadLen(io->rio,NULL);
6604 if (opcode != RDB_MODULE_OPCODE_STRING) goto loaderr;
6605 }
6606 void *s = rdbGenericLoadStringObject(io->rio,
6607 plain ? RDB_LOAD_PLAIN : RDB_LOAD_NONE, lenptr);
6608 if (s == NULL) goto loaderr;
6609 return s;
6610
6611loaderr:
6612 moduleRDBLoadError(io);
6613 return NULL;
6614}
6615
6616/* In the context of the rdb_load method of a module data type, loads a string
6617 * from the RDB file, that was previously saved with RedisModule_SaveString()
6618 * functions family.
6619 *
6620 * The returned string is a newly allocated RedisModuleString object, and
6621 * the user should at some point free it with a call to RedisModule_FreeString().
6622 *
6623 * If the data structure does not store strings as RedisModuleString objects,
6624 * the similar function RedisModule_LoadStringBuffer() could be used instead. */
6625RedisModuleString *RM_LoadString(RedisModuleIO *io) {
6626 return moduleLoadString(io,0,NULL);
6627}
6628
6629/* Like RedisModule_LoadString() but returns a heap allocated string that
6630 * was allocated with RedisModule_Alloc(), and can be resized or freed with
6631 * RedisModule_Realloc() or RedisModule_Free().
6632 *
6633 * The size of the string is stored at '*lenptr' if not NULL.
6634 * The returned string is not automatically NULL terminated, it is loaded
6635 * exactly as it was stored inside the RDB file. */
6636char *RM_LoadStringBuffer(RedisModuleIO *io, size_t *lenptr) {
6637 return moduleLoadString(io,1,lenptr);
6638}
6639
6640/* In the context of the rdb_save method of a module data type, saves a double
6641 * value to the RDB file. The double can be a valid number, a NaN or infinity.
6642 * It is possible to load back the value with RedisModule_LoadDouble(). */
6643void RM_SaveDouble(RedisModuleIO *io, double value) {
6644 if (io->error) return;
6645 /* Save opcode. */
6646 int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_DOUBLE);
6647 if (retval == -1) goto saveerr;
6648 io->bytes += retval;
6649 /* Save value. */
6650 retval = rdbSaveBinaryDoubleValue(io->rio, value);
6651 if (retval == -1) goto saveerr;
6652 io->bytes += retval;
6653 return;
6654
6655saveerr:
6656 io->error = 1;
6657}
6658
6659/* In the context of the rdb_save method of a module data type, loads back the
6660 * double value saved by RedisModule_SaveDouble(). */
6661double RM_LoadDouble(RedisModuleIO *io) {
6662 if (io->error) return 0;
6663 if (io->ver == 2) {
6664 uint64_t opcode = rdbLoadLen(io->rio,NULL);
6665 if (opcode != RDB_MODULE_OPCODE_DOUBLE) goto loaderr;
6666 }
6667 double value;
6668 int retval = rdbLoadBinaryDoubleValue(io->rio, &value);
6669 if (retval == -1) goto loaderr;
6670 return value;
6671
6672loaderr:
6673 moduleRDBLoadError(io);
6674 return 0;
6675}
6676
6677/* In the context of the rdb_save method of a module data type, saves a float
6678 * value to the RDB file. The float can be a valid number, a NaN or infinity.
6679 * It is possible to load back the value with RedisModule_LoadFloat(). */
6680void RM_SaveFloat(RedisModuleIO *io, float value) {
6681 if (io->error) return;
6682 /* Save opcode. */
6683 int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_FLOAT);
6684 if (retval == -1) goto saveerr;
6685 io->bytes += retval;
6686 /* Save value. */
6687 retval = rdbSaveBinaryFloatValue(io->rio, value);
6688 if (retval == -1) goto saveerr;
6689 io->bytes += retval;
6690 return;
6691
6692saveerr:
6693 io->error = 1;
6694}
6695
6696/* In the context of the rdb_save method of a module data type, loads back the
6697 * float value saved by RedisModule_SaveFloat(). */
6698float RM_LoadFloat(RedisModuleIO *io) {
6699 if (io->error) return 0;
6700 if (io->ver == 2) {
6701 uint64_t opcode = rdbLoadLen(io->rio,NULL);
6702 if (opcode != RDB_MODULE_OPCODE_FLOAT) goto loaderr;
6703 }
6704 float value;
6705 int retval = rdbLoadBinaryFloatValue(io->rio, &value);
6706 if (retval == -1) goto loaderr;
6707 return value;
6708
6709loaderr:
6710 moduleRDBLoadError(io);
6711 return 0;
6712}
6713
6714/* In the context of the rdb_save method of a module data type, saves a long double
6715 * value to the RDB file. The double can be a valid number, a NaN or infinity.
6716 * It is possible to load back the value with RedisModule_LoadLongDouble(). */
6717void RM_SaveLongDouble(RedisModuleIO *io, long double value) {
6718 if (io->error) return;
6719 char buf[MAX_LONG_DOUBLE_CHARS];
6720 /* Long double has different number of bits in different platforms, so we
6721 * save it as a string type. */
6722 size_t len = ld2string(buf,sizeof(buf),value,LD_STR_HEX);
6723 RM_SaveStringBuffer(io,buf,len);
6724}
6725
6726/* In the context of the rdb_save method of a module data type, loads back the
6727 * long double value saved by RedisModule_SaveLongDouble(). */
6728long double RM_LoadLongDouble(RedisModuleIO *io) {
6729 if (io->error) return 0;
6730 long double value;
6731 size_t len;
6732 char* str = RM_LoadStringBuffer(io,&len);
6733 if (!str) return 0;
6734 string2ld(str,len,&value);
6735 RM_Free(str);
6736 return value;
6737}
6738
6739/* Iterate over modules, and trigger rdb aux saving for the ones modules types
6740 * who asked for it. */
6741ssize_t rdbSaveModulesAux(rio *rdb, int when) {
6742 size_t total_written = 0;
6743 dictIterator *di = dictGetIterator(modules);
6744 dictEntry *de;
6745
6746 while ((de = dictNext(di)) != NULL) {
6747 struct RedisModule *module = dictGetVal(de);
6748 listIter li;
6749 listNode *ln;
6750
6751 listRewind(module->types,&li);
6752 while((ln = listNext(&li))) {
6753 moduleType *mt = ln->value;
6754 if (!mt->aux_save || !(mt->aux_save_triggers & when))
6755 continue;
6756 ssize_t ret = rdbSaveSingleModuleAux(rdb, when, mt);
6757 if (ret==-1) {
6758 dictReleaseIterator(di);
6759 return -1;
6760 }
6761 total_written += ret;
6762 }
6763 }
6764
6765 dictReleaseIterator(di);
6766 return total_written;
6767}
6768
6769/* --------------------------------------------------------------------------
6770 * ## Key digest API (DEBUG DIGEST interface for modules types)
6771 * -------------------------------------------------------------------------- */
6772
6773/* Add a new element to the digest. This function can be called multiple times
6774 * one element after the other, for all the elements that constitute a given
6775 * data structure. The function call must be followed by the call to
6776 * `RedisModule_DigestEndSequence` eventually, when all the elements that are
6777 * always in a given order are added. See the Redis Modules data types
6778 * documentation for more info. However this is a quick example that uses Redis
6779 * data types as an example.
6780 *
6781 * To add a sequence of unordered elements (for example in the case of a Redis
6782 * Set), the pattern to use is:
6783 *
6784 * foreach element {
6785 * AddElement(element);
6786 * EndSequence();
6787 * }
6788 *
6789 * Because Sets are not ordered, so every element added has a position that
6790 * does not depend from the other. However if instead our elements are
6791 * ordered in pairs, like field-value pairs of a Hash, then one should
6792 * use:
6793 *
6794 * foreach key,value {
6795 * AddElement(key);
6796 * AddElement(value);
6797 * EndSequence();
6798 * }
6799 *
6800 * Because the key and value will be always in the above order, while instead
6801 * the single key-value pairs, can appear in any position into a Redis hash.
6802 *
6803 * A list of ordered elements would be implemented with:
6804 *
6805 * foreach element {
6806 * AddElement(element);
6807 * }
6808 * EndSequence();
6809 *
6810 */
6811void RM_DigestAddStringBuffer(RedisModuleDigest *md, const char *ele, size_t len) {
6812 mixDigest(md->o,ele,len);
6813}
6814
6815/* Like `RedisModule_DigestAddStringBuffer()` but takes a `long long` as input
6816 * that gets converted into a string before adding it to the digest. */
6817void RM_DigestAddLongLong(RedisModuleDigest *md, long long ll) {
6818 char buf[LONG_STR_SIZE];
6819 size_t len = ll2string(buf,sizeof(buf),ll);
6820 mixDigest(md->o,buf,len);
6821}
6822
6823/* See the documentation for `RedisModule_DigestAddElement()`. */
6824void RM_DigestEndSequence(RedisModuleDigest *md) {
6825 xorDigest(md->x,md->o,sizeof(md->o));
6826 memset(md->o,0,sizeof(md->o));
6827}
6828
6829/* Decode a serialized representation of a module data type 'mt', in a specific encoding version 'encver'
6830 * from string 'str' and return a newly allocated value, or NULL if decoding failed.
6831 *
6832 * This call basically reuses the 'rdb_load' callback which module data types
6833 * implement in order to allow a module to arbitrarily serialize/de-serialize
6834 * keys, similar to how the Redis 'DUMP' and 'RESTORE' commands are implemented.
6835 *
6836 * Modules should generally use the REDISMODULE_OPTIONS_HANDLE_IO_ERRORS flag and
6837 * make sure the de-serialization code properly checks and handles IO errors
6838 * (freeing allocated buffers and returning a NULL).
6839 *
6840 * If this is NOT done, Redis will handle corrupted (or just truncated) serialized
6841 * data by producing an error message and terminating the process.
6842 */
6843void *RM_LoadDataTypeFromStringEncver(const RedisModuleString *str, const moduleType *mt, int encver) {
6844 rio payload;
6845 RedisModuleIO io;
6846 void *ret;
6847
6848 rioInitWithBuffer(&payload, str->ptr);
6849 moduleInitIOContext(io,(moduleType *)mt,&payload,NULL,-1);
6850
6851 /* All RM_Save*() calls always write a version 2 compatible format, so we
6852 * need to make sure we read the same.
6853 */
6854 io.ver = 2;
6855 ret = mt->rdb_load(&io,encver);
6856 if (io.ctx) {
6857 moduleFreeContext(io.ctx);
6858 zfree(io.ctx);
6859 }
6860 return ret;
6861}
6862
6863/* Similar to RM_LoadDataTypeFromStringEncver, original version of the API, kept
6864 * for backward compatibility.
6865 */
6866void *RM_LoadDataTypeFromString(const RedisModuleString *str, const moduleType *mt) {
6867 return RM_LoadDataTypeFromStringEncver(str, mt, 0);
6868}
6869
6870/* Encode a module data type 'mt' value 'data' into serialized form, and return it
6871 * as a newly allocated RedisModuleString.
6872 *
6873 * This call basically reuses the 'rdb_save' callback which module data types
6874 * implement in order to allow a module to arbitrarily serialize/de-serialize
6875 * keys, similar to how the Redis 'DUMP' and 'RESTORE' commands are implemented.
6876 */
6877RedisModuleString *RM_SaveDataTypeToString(RedisModuleCtx *ctx, void *data, const moduleType *mt) {
6878 rio payload;
6879 RedisModuleIO io;
6880
6881 rioInitWithBuffer(&payload,sdsempty());
6882 moduleInitIOContext(io,(moduleType *)mt,&payload,NULL,-1);
6883 mt->rdb_save(&io,data);
6884 if (io.ctx) {
6885 moduleFreeContext(io.ctx);
6886 zfree(io.ctx);
6887 }
6888 if (io.error) {
6889 return NULL;
6890 } else {
6891 robj *str = createObject(OBJ_STRING,payload.io.buffer.ptr);
6892 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,str);
6893 return str;
6894 }
6895}
6896
6897/* Returns the name of the key currently being processed. */
6898const RedisModuleString *RM_GetKeyNameFromDigest(RedisModuleDigest *dig) {
6899 return dig->key;
6900}
6901
6902/* Returns the database id of the key currently being processed. */
6903int RM_GetDbIdFromDigest(RedisModuleDigest *dig) {
6904 return dig->dbid;
6905}
6906/* --------------------------------------------------------------------------
6907 * ## AOF API for modules data types
6908 * -------------------------------------------------------------------------- */
6909
6910/* Emits a command into the AOF during the AOF rewriting process. This function
6911 * is only called in the context of the aof_rewrite method of data types exported
6912 * by a module. The command works exactly like RedisModule_Call() in the way
6913 * the parameters are passed, but it does not return anything as the error
6914 * handling is performed by Redis itself. */
6915void RM_EmitAOF(RedisModuleIO *io, const char *cmdname, const char *fmt, ...) {
6916 if (io->error) return;
6917 struct redisCommand *cmd;
6918 robj **argv = NULL;
6919 int argc = 0, flags = 0, j;
6920 va_list ap;
6921
6922 cmd = lookupCommandByCString((char*)cmdname);
6923 if (!cmd) {
6924 serverLog(LL_WARNING,
6925 "Fatal: AOF method for module data type '%s' tried to "
6926 "emit unknown command '%s'",
6927 io->type->name, cmdname);
6928 io->error = 1;
6929 errno = EINVAL;
6930 return;
6931 }
6932
6933 /* Emit the arguments into the AOF in Redis protocol format. */
6934 va_start(ap, fmt);
6935 argv = moduleCreateArgvFromUserFormat(cmdname,fmt,&argc,NULL,&flags,ap);
6936 va_end(ap);
6937 if (argv == NULL) {
6938 serverLog(LL_WARNING,
6939 "Fatal: AOF method for module data type '%s' tried to "
6940 "call RedisModule_EmitAOF() with wrong format specifiers '%s'",
6941 io->type->name, fmt);
6942 io->error = 1;
6943 errno = EINVAL;
6944 return;
6945 }
6946
6947 /* Bulk count. */
6948 if (!io->error && rioWriteBulkCount(io->rio,'*',argc) == 0)
6949 io->error = 1;
6950
6951 /* Arguments. */
6952 for (j = 0; j < argc; j++) {
6953 if (!io->error && rioWriteBulkObject(io->rio,argv[j]) == 0)
6954 io->error = 1;
6955 decrRefCount(argv[j]);
6956 }
6957 zfree(argv);
6958 return;
6959}
6960
6961/* --------------------------------------------------------------------------
6962 * ## IO context handling
6963 * -------------------------------------------------------------------------- */
6964
6965RedisModuleCtx *RM_GetContextFromIO(RedisModuleIO *io) {
6966 if (io->ctx) return io->ctx; /* Can't have more than one... */
6967 io->ctx = zmalloc(sizeof(RedisModuleCtx));
6968 moduleCreateContext(io->ctx, io->type->module, REDISMODULE_CTX_NONE);
6969 return io->ctx;
6970}
6971
6972/* Returns the name of the key currently being processed.
6973 * There is no guarantee that the key name is always available, so this may return NULL.
6974 */
6975const RedisModuleString *RM_GetKeyNameFromIO(RedisModuleIO *io) {
6976 return io->key;
6977}
6978
6979/* Returns a RedisModuleString with the name of the key from RedisModuleKey. */
6980const RedisModuleString *RM_GetKeyNameFromModuleKey(RedisModuleKey *key) {
6981 return key ? key->key : NULL;
6982}
6983
6984/* Returns a database id of the key from RedisModuleKey. */
6985int RM_GetDbIdFromModuleKey(RedisModuleKey *key) {
6986 return key ? key->db->id : -1;
6987}
6988
6989/* Returns the database id of the key currently being processed.
6990 * There is no guarantee that this info is always available, so this may return -1.
6991 */
6992int RM_GetDbIdFromIO(RedisModuleIO *io) {
6993 return io->dbid;
6994}
6995
6996/* --------------------------------------------------------------------------
6997 * ## Logging
6998 * -------------------------------------------------------------------------- */
6999
7000/* This is the low level function implementing both:
7001 *
7002 * RM_Log()
7003 * RM_LogIOError()
7004 *
7005 */
7006void moduleLogRaw(RedisModule *module, const char *levelstr, const char *fmt, va_list ap) {
7007 char msg[LOG_MAX_LEN];
7008 size_t name_len;
7009 int level;
7010
7011 if (!strcasecmp(levelstr,"debug")) level = LL_DEBUG;
7012 else if (!strcasecmp(levelstr,"verbose")) level = LL_VERBOSE;
7013 else if (!strcasecmp(levelstr,"notice")) level = LL_NOTICE;
7014 else if (!strcasecmp(levelstr,"warning")) level = LL_WARNING;
7015 else level = LL_VERBOSE; /* Default. */
7016
7017 if (level < server.verbosity) return;
7018
7019 name_len = snprintf(msg, sizeof(msg),"<%s> ", module? module->name: "module");
7020 vsnprintf(msg + name_len, sizeof(msg) - name_len, fmt, ap);
7021 serverLogRaw(level,msg);
7022}
7023
7024/* Produces a log message to the standard Redis log, the format accepts
7025 * printf-alike specifiers, while level is a string describing the log
7026 * level to use when emitting the log, and must be one of the following:
7027 *
7028 * * "debug" (`REDISMODULE_LOGLEVEL_DEBUG`)
7029 * * "verbose" (`REDISMODULE_LOGLEVEL_VERBOSE`)
7030 * * "notice" (`REDISMODULE_LOGLEVEL_NOTICE`)
7031 * * "warning" (`REDISMODULE_LOGLEVEL_WARNING`)
7032 *
7033 * If the specified log level is invalid, verbose is used by default.
7034 * There is a fixed limit to the length of the log line this function is able
7035 * to emit, this limit is not specified but is guaranteed to be more than
7036 * a few lines of text.
7037 *
7038 * The ctx argument may be NULL if cannot be provided in the context of the
7039 * caller for instance threads or callbacks, in which case a generic "module"
7040 * will be used instead of the module name.
7041 */
7042void RM_Log(RedisModuleCtx *ctx, const char *levelstr, const char *fmt, ...) {
7043 va_list ap;
7044 va_start(ap, fmt);
7045 moduleLogRaw(ctx? ctx->module: NULL,levelstr,fmt,ap);
7046 va_end(ap);
7047}
7048
7049/* Log errors from RDB / AOF serialization callbacks.
7050 *
7051 * This function should be used when a callback is returning a critical
7052 * error to the caller since cannot load or save the data for some
7053 * critical reason. */
7054void RM_LogIOError(RedisModuleIO *io, const char *levelstr, const char *fmt, ...) {
7055 va_list ap;
7056 va_start(ap, fmt);
7057 moduleLogRaw(io->type->module,levelstr,fmt,ap);
7058 va_end(ap);
7059}
7060
7061/* Redis-like assert function.
7062 *
7063 * The macro `RedisModule_Assert(expression)` is recommended, rather than
7064 * calling this function directly.
7065 *
7066 * A failed assertion will shut down the server and produce logging information
7067 * that looks identical to information generated by Redis itself.
7068 */
7069void RM__Assert(const char *estr, const char *file, int line) {
7070 _serverAssert(estr, file, line);
7071}
7072
7073/* Allows adding event to the latency monitor to be observed by the LATENCY
7074 * command. The call is skipped if the latency is smaller than the configured
7075 * latency-monitor-threshold. */
7076void RM_LatencyAddSample(const char *event, mstime_t latency) {
7077 if (latency >= server.latency_monitor_threshold)
7078 latencyAddSample(event, latency);
7079}
7080
7081/* --------------------------------------------------------------------------
7082 * ## Blocking clients from modules
7083 *
7084 * For a guide about blocking commands in modules, see
7085 * https://redis.io/topics/modules-blocking-ops.
7086 * -------------------------------------------------------------------------- */
7087
7088/* This is called from blocked.c in order to unblock a client: may be called
7089 * for multiple reasons while the client is in the middle of being blocked
7090 * because the client is terminated, but is also called for cleanup when a
7091 * client is unblocked in a clean way after replaying.
7092 *
7093 * What we do here is just to set the client to NULL in the redis module
7094 * blocked client handle. This way if the client is terminated while there
7095 * is a pending threaded operation involving the blocked client, we'll know
7096 * that the client no longer exists and no reply callback should be called.
7097 *
7098 * The structure RedisModuleBlockedClient will be always deallocated when
7099 * running the list of clients blocked by a module that need to be unblocked. */
7100void unblockClientFromModule(client *c) {
7101 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
7102
7103 /* Call the disconnection callback if any. Note that
7104 * bc->disconnect_callback is set to NULL if the client gets disconnected
7105 * by the module itself or because of a timeout, so the callback will NOT
7106 * get called if this is not an actual disconnection event. */
7107 if (bc->disconnect_callback) {
7108 RedisModuleCtx ctx;
7109 moduleCreateContext(&ctx, bc->module, REDISMODULE_CTX_NONE);
7110 ctx.blocked_privdata = bc->privdata;
7111 ctx.client = bc->client;
7112 bc->disconnect_callback(&ctx,bc);
7113 moduleFreeContext(&ctx);
7114 }
7115
7116 /* If we made it here and client is still blocked it means that the command
7117 * timed-out, client was killed or disconnected and disconnect_callback was
7118 * not implemented (or it was, but RM_UnblockClient was not called from
7119 * within it, as it should).
7120 * We must call moduleUnblockClient in order to free privdata and
7121 * RedisModuleBlockedClient.
7122 *
7123 * Note that we only do that for clients that are blocked on keys, for which
7124 * the contract is that the module should not call RM_UnblockClient under
7125 * normal circumstances.
7126 * Clients implementing threads and working with private data should be
7127 * aware that calling RM_UnblockClient for every blocked client is their
7128 * responsibility, and if they fail to do so memory may leak. Ideally they
7129 * should implement the disconnect and timeout callbacks and call
7130 * RM_UnblockClient, but any other way is also acceptable. */
7131 if (bc->blocked_on_keys && !bc->unblocked)
7132 moduleUnblockClient(c);
7133
7134 bc->client = NULL;
7135}
7136
7137/* Block a client in the context of a module: this function implements both
7138 * RM_BlockClient() and RM_BlockClientOnKeys() depending on the fact the
7139 * keys are passed or not.
7140 *
7141 * When not blocking for keys, the keys, numkeys, and privdata parameters are
7142 * not needed. The privdata in that case must be NULL, since later is
7143 * RM_UnblockClient() that will provide some private data that the reply
7144 * callback will receive.
7145 *
7146 * Instead when blocking for keys, normally RM_UnblockClient() will not be
7147 * called (because the client will unblock when the key is modified), so
7148 * 'privdata' should be provided in that case, so that once the client is
7149 * unlocked and the reply callback is called, it will receive its associated
7150 * private data.
7151 *
7152 * Even when blocking on keys, RM_UnblockClient() can be called however, but
7153 * in that case the privdata argument is disregarded, because we pass the
7154 * reply callback the privdata that is set here while blocking.
7155 *
7156 */
7157RedisModuleBlockedClient *moduleBlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms, RedisModuleString **keys, int numkeys, void *privdata) {
7158 client *c = ctx->client;
7159 int islua = scriptIsRunning();
7160 int ismulti = server.in_exec;
7161
7162 c->bpop.module_blocked_handle = zmalloc(sizeof(RedisModuleBlockedClient));
7163 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
7164 ctx->module->blocked_clients++;
7165
7166 /* We need to handle the invalid operation of calling modules blocking
7167 * commands from Lua or MULTI. We actually create an already aborted
7168 * (client set to NULL) blocked client handle, and actually reply with
7169 * an error. */
7170 mstime_t timeout = timeout_ms ? (mstime()+timeout_ms) : 0;
7171 bc->client = (islua || ismulti) ? NULL : c;
7172 bc->module = ctx->module;
7173 bc->reply_callback = reply_callback;
7174 bc->timeout_callback = timeout_callback;
7175 bc->disconnect_callback = NULL; /* Set by RM_SetDisconnectCallback() */
7176 bc->free_privdata = free_privdata;
7177 bc->privdata = privdata;
7178 bc->reply_client = moduleAllocTempClient();
7179 bc->thread_safe_ctx_client = moduleAllocTempClient();
7180 if (bc->client)
7181 bc->reply_client->resp = bc->client->resp;
7182 bc->dbid = c->db->id;
7183 bc->blocked_on_keys = keys != NULL;
7184 bc->unblocked = 0;
7185 bc->background_timer = 0;
7186 bc->background_duration = 0;
7187 c->bpop.timeout = timeout;
7188
7189 if (islua || ismulti) {
7190 c->bpop.module_blocked_handle = NULL;
7191 addReplyError(c, islua ?
7192 "Blocking module command called from Lua script" :
7193 "Blocking module command called from transaction");
7194 } else {
7195 if (keys) {
7196 blockForKeys(c,BLOCKED_MODULE,keys,numkeys,-1,timeout,NULL,NULL,NULL);
7197 } else {
7198 blockClient(c,BLOCKED_MODULE);
7199 }
7200 }
7201 return bc;
7202}
7203
7204/* This function is called from module.c in order to check if a module
7205 * blocked for BLOCKED_MODULE and subtype 'on keys' (bc->blocked_on_keys true)
7206 * can really be unblocked, since the module was able to serve the client.
7207 * If the callback returns REDISMODULE_OK, then the client can be unblocked,
7208 * otherwise the client remains blocked and we'll retry again when one of
7209 * the keys it blocked for becomes "ready" again.
7210 * This function returns 1 if client was served (and should be unblocked) */
7211int moduleTryServeClientBlockedOnKey(client *c, robj *key) {
7212 int served = 0;
7213 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
7214
7215 /* Protect against re-processing: don't serve clients that are already
7216 * in the unblocking list for any reason (including RM_UnblockClient()
7217 * explicit call). See #6798. */
7218 if (bc->unblocked) return 0;
7219
7220 RedisModuleCtx ctx;
7221 moduleCreateContext(&ctx, bc->module, REDISMODULE_CTX_BLOCKED_REPLY);
7222 ctx.blocked_ready_key = key;
7223 ctx.blocked_privdata = bc->privdata;
7224 ctx.client = bc->client;
7225 ctx.blocked_client = bc;
7226 if (bc->reply_callback(&ctx,(void**)c->argv,c->argc) == REDISMODULE_OK)
7227 served = 1;
7228 moduleFreeContext(&ctx);
7229 return served;
7230}
7231
7232/* Block a client in the context of a blocking command, returning a handle
7233 * which will be used, later, in order to unblock the client with a call to
7234 * RedisModule_UnblockClient(). The arguments specify callback functions
7235 * and a timeout after which the client is unblocked.
7236 *
7237 * The callbacks are called in the following contexts:
7238 *
7239 * reply_callback: called after a successful RedisModule_UnblockClient()
7240 * call in order to reply to the client and unblock it.
7241 *
7242 * timeout_callback: called when the timeout is reached or if `CLIENT UNBLOCK`
7243 * is invoked, in order to send an error to the client.
7244 *
7245 * free_privdata: called in order to free the private data that is passed
7246 * by RedisModule_UnblockClient() call.
7247 *
7248 * Note: RedisModule_UnblockClient should be called for every blocked client,
7249 * even if client was killed, timed-out or disconnected. Failing to do so
7250 * will result in memory leaks.
7251 *
7252 * There are some cases where RedisModule_BlockClient() cannot be used:
7253 *
7254 * 1. If the client is a Lua script.
7255 * 2. If the client is executing a MULTI block.
7256 *
7257 * In these cases, a call to RedisModule_BlockClient() will **not** block the
7258 * client, but instead produce a specific error reply.
7259 *
7260 * A module that registers a timeout_callback function can also be unblocked
7261 * using the `CLIENT UNBLOCK` command, which will trigger the timeout callback.
7262 * If a callback function is not registered, then the blocked client will be
7263 * treated as if it is not in a blocked state and `CLIENT UNBLOCK` will return
7264 * a zero value.
7265 *
7266 * Measuring background time: By default the time spent in the blocked command
7267 * is not account for the total command duration. To include such time you should
7268 * use RM_BlockedClientMeasureTimeStart() and RM_BlockedClientMeasureTimeEnd() one,
7269 * or multiple times within the blocking command background work.
7270 */
7271RedisModuleBlockedClient *RM_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(RedisModuleCtx*,void*), long long timeout_ms) {
7272 return moduleBlockClient(ctx,reply_callback,timeout_callback,free_privdata,timeout_ms, NULL,0,NULL);
7273}
7274
7275/* This call is similar to RedisModule_BlockClient(), however in this case we
7276 * don't just block the client, but also ask Redis to unblock it automatically
7277 * once certain keys become "ready", that is, contain more data.
7278 *
7279 * Basically this is similar to what a typical Redis command usually does,
7280 * like BLPOP or BZPOPMAX: the client blocks if it cannot be served ASAP,
7281 * and later when the key receives new data (a list push for instance), the
7282 * client is unblocked and served.
7283 *
7284 * However in the case of this module API, when the client is unblocked?
7285 *
7286 * 1. If you block on a key of a type that has blocking operations associated,
7287 * like a list, a sorted set, a stream, and so forth, the client may be
7288 * unblocked once the relevant key is targeted by an operation that normally
7289 * unblocks the native blocking operations for that type. So if we block
7290 * on a list key, an RPUSH command may unblock our client and so forth.
7291 * 2. If you are implementing your native data type, or if you want to add new
7292 * unblocking conditions in addition to "1", you can call the modules API
7293 * RedisModule_SignalKeyAsReady().
7294 *
7295 * Anyway we can't be sure if the client should be unblocked just because the
7296 * key is signaled as ready: for instance a successive operation may change the
7297 * key, or a client in queue before this one can be served, modifying the key
7298 * as well and making it empty again. So when a client is blocked with
7299 * RedisModule_BlockClientOnKeys() the reply callback is not called after
7300 * RM_UnblockClient() is called, but every time a key is signaled as ready:
7301 * if the reply callback can serve the client, it returns REDISMODULE_OK
7302 * and the client is unblocked, otherwise it will return REDISMODULE_ERR
7303 * and we'll try again later.
7304 *
7305 * The reply callback can access the key that was signaled as ready by
7306 * calling the API RedisModule_GetBlockedClientReadyKey(), that returns
7307 * just the string name of the key as a RedisModuleString object.
7308 *
7309 * Thanks to this system we can setup complex blocking scenarios, like
7310 * unblocking a client only if a list contains at least 5 items or other
7311 * more fancy logics.
7312 *
7313 * Note that another difference with RedisModule_BlockClient(), is that here
7314 * we pass the private data directly when blocking the client: it will
7315 * be accessible later in the reply callback. Normally when blocking with
7316 * RedisModule_BlockClient() the private data to reply to the client is
7317 * passed when calling RedisModule_UnblockClient() but here the unblocking
7318 * is performed by Redis itself, so we need to have some private data before
7319 * hand. The private data is used to store any information about the specific
7320 * unblocking operation that you are implementing. Such information will be
7321 * freed using the free_privdata callback provided by the user.
7322 *
7323 * However the reply callback will be able to access the argument vector of
7324 * the command, so the private data is often not needed.
7325 *
7326 * Note: Under normal circumstances RedisModule_UnblockClient should not be
7327 * called for clients that are blocked on keys (Either the key will
7328 * become ready or a timeout will occur). If for some reason you do want
7329 * to call RedisModule_UnblockClient it is possible: Client will be
7330 * handled as if it were timed-out (You must implement the timeout
7331 * callback in that case).
7332 */
7333RedisModuleBlockedClient *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) {
7334 return moduleBlockClient(ctx,reply_callback,timeout_callback,free_privdata,timeout_ms, keys,numkeys,privdata);
7335}
7336
7337/* This function is used in order to potentially unblock a client blocked
7338 * on keys with RedisModule_BlockClientOnKeys(). When this function is called,
7339 * all the clients blocked for this key will get their reply_callback called.
7340 *
7341 * Note: The function has no effect if the signaled key doesn't exist. */
7342void RM_SignalKeyAsReady(RedisModuleCtx *ctx, RedisModuleString *key) {
7343 signalKeyAsReady(ctx->client->db, key, OBJ_MODULE);
7344}
7345
7346/* Implements RM_UnblockClient() and moduleUnblockClient(). */
7347int moduleUnblockClientByHandle(RedisModuleBlockedClient *bc, void *privdata) {
7348 pthread_mutex_lock(&moduleUnblockedClientsMutex);
7349 if (!bc->blocked_on_keys) bc->privdata = privdata;
7350 bc->unblocked = 1;
7351 if (listLength(moduleUnblockedClients) == 0) {
7352 if (write(server.module_pipe[1],"A",1) != 1) {
7353 /* Ignore the error, this is best-effort. */
7354 }
7355 }
7356 listAddNodeTail(moduleUnblockedClients,bc);
7357 pthread_mutex_unlock(&moduleUnblockedClientsMutex);
7358 return REDISMODULE_OK;
7359}
7360
7361/* This API is used by the Redis core to unblock a client that was blocked
7362 * by a module. */
7363void moduleUnblockClient(client *c) {
7364 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
7365 moduleUnblockClientByHandle(bc,NULL);
7366}
7367
7368/* Return true if the client 'c' was blocked by a module using
7369 * RM_BlockClientOnKeys(). */
7370int moduleClientIsBlockedOnKeys(client *c) {
7371 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
7372 return bc->blocked_on_keys;
7373}
7374
7375/* Unblock a client blocked by `RedisModule_BlockedClient`. This will trigger
7376 * the reply callbacks to be called in order to reply to the client.
7377 * The 'privdata' argument will be accessible by the reply callback, so
7378 * the caller of this function can pass any value that is needed in order to
7379 * actually reply to the client.
7380 *
7381 * A common usage for 'privdata' is a thread that computes something that
7382 * needs to be passed to the client, included but not limited some slow
7383 * to compute reply or some reply obtained via networking.
7384 *
7385 * Note 1: this function can be called from threads spawned by the module.
7386 *
7387 * Note 2: when we unblock a client that is blocked for keys using the API
7388 * RedisModule_BlockClientOnKeys(), the privdata argument here is not used.
7389 * Unblocking a client that was blocked for keys using this API will still
7390 * require the client to get some reply, so the function will use the
7391 * "timeout" handler in order to do so (The privdata provided in
7392 * RedisModule_BlockClientOnKeys() is accessible from the timeout
7393 * callback via RM_GetBlockedClientPrivateData). */
7394int RM_UnblockClient(RedisModuleBlockedClient *bc, void *privdata) {
7395 if (bc->blocked_on_keys) {
7396 /* In theory the user should always pass the timeout handler as an
7397 * argument, but better to be safe than sorry. */
7398 if (bc->timeout_callback == NULL) return REDISMODULE_ERR;
7399 if (bc->unblocked) return REDISMODULE_OK;
7400 if (bc->client) moduleBlockedClientTimedOut(bc->client);
7401 }
7402 moduleUnblockClientByHandle(bc,privdata);
7403 return REDISMODULE_OK;
7404}
7405
7406/* Abort a blocked client blocking operation: the client will be unblocked
7407 * without firing any callback. */
7408int RM_AbortBlock(RedisModuleBlockedClient *bc) {
7409 bc->reply_callback = NULL;
7410 bc->disconnect_callback = NULL;
7411 return RM_UnblockClient(bc,NULL);
7412}
7413
7414/* Set a callback that will be called if a blocked client disconnects
7415 * before the module has a chance to call RedisModule_UnblockClient()
7416 *
7417 * Usually what you want to do there, is to cleanup your module state
7418 * so that you can call RedisModule_UnblockClient() safely, otherwise
7419 * the client will remain blocked forever if the timeout is large.
7420 *
7421 * Notes:
7422 *
7423 * 1. It is not safe to call Reply* family functions here, it is also
7424 * useless since the client is gone.
7425 *
7426 * 2. This callback is not called if the client disconnects because of
7427 * a timeout. In such a case, the client is unblocked automatically
7428 * and the timeout callback is called.
7429 */
7430void RM_SetDisconnectCallback(RedisModuleBlockedClient *bc, RedisModuleDisconnectFunc callback) {
7431 bc->disconnect_callback = callback;
7432}
7433
7434/* This function will check the moduleUnblockedClients queue in order to
7435 * call the reply callback and really unblock the client.
7436 *
7437 * Clients end into this list because of calls to RM_UnblockClient(),
7438 * however it is possible that while the module was doing work for the
7439 * blocked client, it was terminated by Redis (for timeout or other reasons).
7440 * When this happens the RedisModuleBlockedClient structure in the queue
7441 * will have the 'client' field set to NULL. */
7442void moduleHandleBlockedClients(void) {
7443 listNode *ln;
7444 RedisModuleBlockedClient *bc;
7445
7446 pthread_mutex_lock(&moduleUnblockedClientsMutex);
7447 while (listLength(moduleUnblockedClients)) {
7448 ln = listFirst(moduleUnblockedClients);
7449 bc = ln->value;
7450 client *c = bc->client;
7451 listDelNode(moduleUnblockedClients,ln);
7452 pthread_mutex_unlock(&moduleUnblockedClientsMutex);
7453
7454 /* Release the lock during the loop, as long as we don't
7455 * touch the shared list. */
7456
7457 /* Call the reply callback if the client is valid and we have
7458 * any callback. However the callback is not called if the client
7459 * was blocked on keys (RM_BlockClientOnKeys()), because we already
7460 * called such callback in moduleTryServeClientBlockedOnKey() when
7461 * the key was signaled as ready. */
7462 long long prev_error_replies = server.stat_total_error_replies;
7463 uint64_t reply_us = 0;
7464 if (c && !bc->blocked_on_keys && bc->reply_callback) {
7465 RedisModuleCtx ctx;
7466 moduleCreateContext(&ctx, bc->module, REDISMODULE_CTX_BLOCKED_REPLY);
7467 ctx.blocked_privdata = bc->privdata;
7468 ctx.blocked_ready_key = NULL;
7469 ctx.client = bc->client;
7470 ctx.blocked_client = bc;
7471 monotime replyTimer;
7472 elapsedStart(&replyTimer);
7473 bc->reply_callback(&ctx,(void**)c->argv,c->argc);
7474 reply_us = elapsedUs(replyTimer);
7475 moduleFreeContext(&ctx);
7476 }
7477
7478 /* Free privdata if any. */
7479 if (bc->privdata && bc->free_privdata) {
7480 RedisModuleCtx ctx;
7481 int ctx_flags = c == NULL ? REDISMODULE_CTX_BLOCKED_DISCONNECTED : REDISMODULE_CTX_NONE;
7482 moduleCreateContext(&ctx, bc->module, ctx_flags);
7483 ctx.blocked_privdata = bc->privdata;
7484 ctx.client = bc->client;
7485 bc->free_privdata(&ctx,bc->privdata);
7486 moduleFreeContext(&ctx);
7487 }
7488
7489 /* It is possible that this blocked client object accumulated
7490 * replies to send to the client in a thread safe context.
7491 * We need to glue such replies to the client output buffer and
7492 * free the temporary client we just used for the replies. */
7493 if (c) AddReplyFromClient(c, bc->reply_client);
7494 moduleReleaseTempClient(bc->reply_client);
7495 moduleReleaseTempClient(bc->thread_safe_ctx_client);
7496
7497 /* Update stats now that we've finished the blocking operation.
7498 * This needs to be out of the reply callback above given that a
7499 * module might not define any callback and still do blocking ops.
7500 */
7501 if (c && !bc->blocked_on_keys) {
7502 updateStatsOnUnblock(c, bc->background_duration, reply_us, server.stat_total_error_replies != prev_error_replies);
7503 }
7504
7505 if (c != NULL) {
7506 /* Before unblocking the client, set the disconnect callback
7507 * to NULL, because if we reached this point, the client was
7508 * properly unblocked by the module. */
7509 bc->disconnect_callback = NULL;
7510 unblockClient(c);
7511 /* Put the client in the list of clients that need to write
7512 * if there are pending replies here. This is needed since
7513 * during a non blocking command the client may receive output. */
7514 if (clientHasPendingReplies(c) &&
7515 !(c->flags & CLIENT_PENDING_WRITE))
7516 {
7517 c->flags |= CLIENT_PENDING_WRITE;
7518 listAddNodeHead(server.clients_pending_write,c);
7519 }
7520 }
7521
7522 /* Free 'bc' only after unblocking the client, since it is
7523 * referenced in the client blocking context, and must be valid
7524 * when calling unblockClient(). */
7525 bc->module->blocked_clients--;
7526 zfree(bc);
7527
7528 /* Lock again before to iterate the loop. */
7529 pthread_mutex_lock(&moduleUnblockedClientsMutex);
7530 }
7531 pthread_mutex_unlock(&moduleUnblockedClientsMutex);
7532}
7533
7534/* Check if the specified client can be safely timed out using
7535 * moduleBlockedClientTimedOut().
7536 */
7537int moduleBlockedClientMayTimeout(client *c) {
7538 if (c->btype != BLOCKED_MODULE)
7539 return 1;
7540
7541 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
7542 return (bc && bc->timeout_callback != NULL);
7543}
7544
7545/* Called when our client timed out. After this function unblockClient()
7546 * is called, and it will invalidate the blocked client. So this function
7547 * does not need to do any cleanup. Eventually the module will call the
7548 * API to unblock the client and the memory will be released. */
7549void moduleBlockedClientTimedOut(client *c) {
7550 RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle;
7551
7552 /* Protect against re-processing: don't serve clients that are already
7553 * in the unblocking list for any reason (including RM_UnblockClient()
7554 * explicit call). See #6798. */
7555 if (bc->unblocked) return;
7556
7557 RedisModuleCtx ctx;
7558 moduleCreateContext(&ctx, bc->module, REDISMODULE_CTX_BLOCKED_TIMEOUT);
7559 ctx.client = bc->client;
7560 ctx.blocked_client = bc;
7561 ctx.blocked_privdata = bc->privdata;
7562 long long prev_error_replies = server.stat_total_error_replies;
7563 bc->timeout_callback(&ctx,(void**)c->argv,c->argc);
7564 moduleFreeContext(&ctx);
7565 if (!bc->blocked_on_keys) {
7566 updateStatsOnUnblock(c, bc->background_duration, 0, server.stat_total_error_replies != prev_error_replies);
7567 }
7568 /* For timeout events, we do not want to call the disconnect callback,
7569 * because the blocked client will be automatically disconnected in
7570 * this case, and the user can still hook using the timeout callback. */
7571 bc->disconnect_callback = NULL;
7572}
7573
7574/* Return non-zero if a module command was called in order to fill the
7575 * reply for a blocked client. */
7576int RM_IsBlockedReplyRequest(RedisModuleCtx *ctx) {
7577 return (ctx->flags & REDISMODULE_CTX_BLOCKED_REPLY) != 0;
7578}
7579
7580/* Return non-zero if a module command was called in order to fill the
7581 * reply for a blocked client that timed out. */
7582int RM_IsBlockedTimeoutRequest(RedisModuleCtx *ctx) {
7583 return (ctx->flags & REDISMODULE_CTX_BLOCKED_TIMEOUT) != 0;
7584}
7585
7586/* Get the private data set by RedisModule_UnblockClient() */
7587void *RM_GetBlockedClientPrivateData(RedisModuleCtx *ctx) {
7588 return ctx->blocked_privdata;
7589}
7590
7591/* Get the key that is ready when the reply callback is called in the context
7592 * of a client blocked by RedisModule_BlockClientOnKeys(). */
7593RedisModuleString *RM_GetBlockedClientReadyKey(RedisModuleCtx *ctx) {
7594 return ctx->blocked_ready_key;
7595}
7596
7597/* Get the blocked client associated with a given context.
7598 * This is useful in the reply and timeout callbacks of blocked clients,
7599 * before sometimes the module has the blocked client handle references
7600 * around, and wants to cleanup it. */
7601RedisModuleBlockedClient *RM_GetBlockedClientHandle(RedisModuleCtx *ctx) {
7602 return ctx->blocked_client;
7603}
7604
7605/* Return true if when the free callback of a blocked client is called,
7606 * the reason for the client to be unblocked is that it disconnected
7607 * while it was blocked. */
7608int RM_BlockedClientDisconnected(RedisModuleCtx *ctx) {
7609 return (ctx->flags & REDISMODULE_CTX_BLOCKED_DISCONNECTED) != 0;
7610}
7611
7612/* --------------------------------------------------------------------------
7613 * ## Thread Safe Contexts
7614 * -------------------------------------------------------------------------- */
7615
7616/* Return a context which can be used inside threads to make Redis context
7617 * calls with certain modules APIs. If 'bc' is not NULL then the module will
7618 * be bound to a blocked client, and it will be possible to use the
7619 * `RedisModule_Reply*` family of functions to accumulate a reply for when the
7620 * client will be unblocked. Otherwise the thread safe context will be
7621 * detached by a specific client.
7622 *
7623 * To call non-reply APIs, the thread safe context must be prepared with:
7624 *
7625 * RedisModule_ThreadSafeContextLock(ctx);
7626 * ... make your call here ...
7627 * RedisModule_ThreadSafeContextUnlock(ctx);
7628 *
7629 * This is not needed when using `RedisModule_Reply*` functions, assuming
7630 * that a blocked client was used when the context was created, otherwise
7631 * no RedisModule_Reply* call should be made at all.
7632 *
7633 * NOTE: If you're creating a detached thread safe context (bc is NULL),
7634 * consider using `RM_GetDetachedThreadSafeContext` which will also retain
7635 * the module ID and thus be more useful for logging. */
7636RedisModuleCtx *RM_GetThreadSafeContext(RedisModuleBlockedClient *bc) {
7637 RedisModuleCtx *ctx = zmalloc(sizeof(*ctx));
7638 RedisModule *module = bc ? bc->module : NULL;
7639 int flags = REDISMODULE_CTX_THREAD_SAFE;
7640
7641 /* Creating a new client object is costly. To avoid that, we have an
7642 * internal pool of client objects. In blockClient(), a client object is
7643 * assigned to bc->thread_safe_ctx_client to be used for the thread safe
7644 * context.
7645 * For detached thread safe contexts, we create a new client object.
7646 * Otherwise, as this function can be called from different threads, we
7647 * would need to synchronize access to internal pool of client objects.
7648 * Assuming creating detached context is rare and not that performance
7649 * critical, we avoid synchronizing access to the client pool by creating
7650 * a new client */
7651 if (!bc) flags |= REDISMODULE_CTX_NEW_CLIENT;
7652 moduleCreateContext(ctx, module, flags);
7653 /* Even when the context is associated with a blocked client, we can't
7654 * access it safely from another thread, so we use a fake client here
7655 * in order to keep things like the currently selected database and similar
7656 * things. */
7657 if (bc) {
7658 ctx->blocked_client = bc;
7659 ctx->client = bc->thread_safe_ctx_client;
7660 selectDb(ctx->client,bc->dbid);
7661 if (bc->client) {
7662 ctx->client->id = bc->client->id;
7663 ctx->client->resp = bc->client->resp;
7664 }
7665 }
7666 return ctx;
7667}
7668
7669/* Return a detached thread safe context that is not associated with any
7670 * specific blocked client, but is associated with the module's context.
7671 *
7672 * This is useful for modules that wish to hold a global context over
7673 * a long term, for purposes such as logging. */
7674RedisModuleCtx *RM_GetDetachedThreadSafeContext(RedisModuleCtx *ctx) {
7675 RedisModuleCtx *new_ctx = zmalloc(sizeof(*new_ctx));
7676 /* We create a new client object for the detached context.
7677 * See RM_GetThreadSafeContext() for more information */
7678 moduleCreateContext(new_ctx, ctx->module,
7679 REDISMODULE_CTX_THREAD_SAFE|REDISMODULE_CTX_NEW_CLIENT);
7680 return new_ctx;
7681}
7682
7683/* Release a thread safe context. */
7684void RM_FreeThreadSafeContext(RedisModuleCtx *ctx) {
7685 moduleFreeContext(ctx);
7686 zfree(ctx);
7687}
7688
7689void moduleGILAfterLock() {
7690 /* We should never get here if we already inside a module
7691 * code block which already opened a context. */
7692 serverAssert(server.module_ctx_nesting == 0);
7693 /* Bump up the nesting level to prevent immediate propagation
7694 * of possible RM_Call from th thread */
7695 server.module_ctx_nesting++;
7696}
7697
7698/* Acquire the server lock before executing a thread safe API call.
7699 * This is not needed for `RedisModule_Reply*` calls when there is
7700 * a blocked client connected to the thread safe context. */
7701void RM_ThreadSafeContextLock(RedisModuleCtx *ctx) {
7702 UNUSED(ctx);
7703 moduleAcquireGIL();
7704 moduleGILAfterLock();
7705}
7706
7707/* Similar to RM_ThreadSafeContextLock but this function
7708 * would not block if the server lock is already acquired.
7709 *
7710 * If successful (lock acquired) REDISMODULE_OK is returned,
7711 * otherwise REDISMODULE_ERR is returned and errno is set
7712 * accordingly. */
7713int RM_ThreadSafeContextTryLock(RedisModuleCtx *ctx) {
7714 UNUSED(ctx);
7715
7716 int res = moduleTryAcquireGIL();
7717 if(res != 0) {
7718 errno = res;
7719 return REDISMODULE_ERR;
7720 }
7721 moduleGILAfterLock();
7722 return REDISMODULE_OK;
7723}
7724
7725void moduleGILBeforeUnlock() {
7726 /* We should never get here if we already inside a module
7727 * code block which already opened a context, except
7728 * the bump-up from moduleGILAcquired. */
7729 serverAssert(server.module_ctx_nesting == 1);
7730 /* Restore ctx_nesting and propagate pending commands
7731 * (because it's u clear when thread safe contexts are
7732 * released we have to propagate here). */
7733 server.module_ctx_nesting--;
7734 propagatePendingCommands();
7735
7736 if (server.busy_module_yield_flags) {
7737 blockingOperationEnds();
7738 server.busy_module_yield_flags = BUSY_MODULE_YIELD_NONE;
7739 if (server.current_client)
7740 unprotectClient(server.current_client);
7741 unblockPostponedClients();
7742 }
7743}
7744
7745/* Release the server lock after a thread safe API call was executed. */
7746void RM_ThreadSafeContextUnlock(RedisModuleCtx *ctx) {
7747 UNUSED(ctx);
7748 moduleGILBeforeUnlock();
7749 moduleReleaseGIL();
7750}
7751
7752void moduleAcquireGIL(void) {
7753 pthread_mutex_lock(&moduleGIL);
7754}
7755
7756int moduleTryAcquireGIL(void) {
7757 return pthread_mutex_trylock(&moduleGIL);
7758}
7759
7760void moduleReleaseGIL(void) {
7761 pthread_mutex_unlock(&moduleGIL);
7762}
7763
7764
7765/* --------------------------------------------------------------------------
7766 * ## Module Keyspace Notifications API
7767 * -------------------------------------------------------------------------- */
7768
7769/* Subscribe to keyspace notifications. This is a low-level version of the
7770 * keyspace-notifications API. A module can register callbacks to be notified
7771 * when keyspace events occur.
7772 *
7773 * Notification events are filtered by their type (string events, set events,
7774 * etc), and the subscriber callback receives only events that match a specific
7775 * mask of event types.
7776 *
7777 * When subscribing to notifications with RedisModule_SubscribeToKeyspaceEvents
7778 * the module must provide an event type-mask, denoting the events the subscriber
7779 * is interested in. This can be an ORed mask of any of the following flags:
7780 *
7781 * - REDISMODULE_NOTIFY_GENERIC: Generic commands like DEL, EXPIRE, RENAME
7782 * - REDISMODULE_NOTIFY_STRING: String events
7783 * - REDISMODULE_NOTIFY_LIST: List events
7784 * - REDISMODULE_NOTIFY_SET: Set events
7785 * - REDISMODULE_NOTIFY_HASH: Hash events
7786 * - REDISMODULE_NOTIFY_ZSET: Sorted Set events
7787 * - REDISMODULE_NOTIFY_EXPIRED: Expiration events
7788 * - REDISMODULE_NOTIFY_EVICTED: Eviction events
7789 * - REDISMODULE_NOTIFY_STREAM: Stream events
7790 * - REDISMODULE_NOTIFY_MODULE: Module types events
7791 * - REDISMODULE_NOTIFY_KEYMISS: Key-miss events
7792 * - REDISMODULE_NOTIFY_ALL: All events (Excluding REDISMODULE_NOTIFY_KEYMISS)
7793 * - REDISMODULE_NOTIFY_LOADED: A special notification available only for modules,
7794 * indicates that the key was loaded from persistence.
7795 * Notice, when this event fires, the given key
7796 * can not be retained, use RM_CreateStringFromString
7797 * instead.
7798 *
7799 * We do not distinguish between key events and keyspace events, and it is up
7800 * to the module to filter the actions taken based on the key.
7801 *
7802 * The subscriber signature is:
7803 *
7804 * int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type,
7805 * const char *event,
7806 * RedisModuleString *key);
7807 *
7808 * `type` is the event type bit, that must match the mask given at registration
7809 * time. The event string is the actual command being executed, and key is the
7810 * relevant Redis key.
7811 *
7812 * Notification callback gets executed with a redis context that can not be
7813 * used to send anything to the client, and has the db number where the event
7814 * occurred as its selected db number.
7815 *
7816 * Notice that it is not necessary to enable notifications in redis.conf for
7817 * module notifications to work.
7818 *
7819 * Warning: the notification callbacks are performed in a synchronous manner,
7820 * so notification callbacks must to be fast, or they would slow Redis down.
7821 * If you need to take long actions, use threads to offload them.
7822 *
7823 * See https://redis.io/topics/notifications for more information.
7824 */
7825int RM_SubscribeToKeyspaceEvents(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc callback) {
7826 RedisModuleKeyspaceSubscriber *sub = zmalloc(sizeof(*sub));
7827 sub->module = ctx->module;
7828 sub->event_mask = types;
7829 sub->notify_callback = callback;
7830 sub->active = 0;
7831
7832 listAddNodeTail(moduleKeyspaceSubscribers, sub);
7833 return REDISMODULE_OK;
7834}
7835
7836/* Get the configured bitmap of notify-keyspace-events (Could be used
7837 * for additional filtering in RedisModuleNotificationFunc) */
7838int RM_GetNotifyKeyspaceEvents() {
7839 return server.notify_keyspace_events;
7840}
7841
7842/* Expose notifyKeyspaceEvent to modules */
7843int RM_NotifyKeyspaceEvent(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key) {
7844 if (!ctx || !ctx->client)
7845 return REDISMODULE_ERR;
7846 notifyKeyspaceEvent(type, (char *)event, key, ctx->client->db->id);
7847 return REDISMODULE_OK;
7848}
7849
7850/* Dispatcher for keyspace notifications to module subscriber functions.
7851 * This gets called only if at least one module requested to be notified on
7852 * keyspace notifications */
7853void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) {
7854 /* Don't do anything if there aren't any subscribers */
7855 if (listLength(moduleKeyspaceSubscribers) == 0) return;
7856
7857 listIter li;
7858 listNode *ln;
7859 listRewind(moduleKeyspaceSubscribers,&li);
7860
7861 /* Remove irrelevant flags from the type mask */
7862 type &= ~(NOTIFY_KEYEVENT | NOTIFY_KEYSPACE);
7863
7864 while((ln = listNext(&li))) {
7865 RedisModuleKeyspaceSubscriber *sub = ln->value;
7866 /* Only notify subscribers on events matching the registration,
7867 * and avoid subscribers triggering themselves */
7868 if ((sub->event_mask & type) && sub->active == 0) {
7869 RedisModuleCtx ctx;
7870 moduleCreateContext(&ctx, sub->module, REDISMODULE_CTX_TEMP_CLIENT);
7871 selectDb(ctx.client, dbid);
7872
7873 /* mark the handler as active to avoid reentrant loops.
7874 * If the subscriber performs an action triggering itself,
7875 * it will not be notified about it. */
7876 sub->active = 1;
7877 sub->notify_callback(&ctx, type, event, key);
7878 sub->active = 0;
7879 moduleFreeContext(&ctx);
7880 }
7881 }
7882}
7883
7884/* Unsubscribe any notification subscribers this module has upon unloading */
7885void moduleUnsubscribeNotifications(RedisModule *module) {
7886 listIter li;
7887 listNode *ln;
7888 listRewind(moduleKeyspaceSubscribers,&li);
7889 while((ln = listNext(&li))) {
7890 RedisModuleKeyspaceSubscriber *sub = ln->value;
7891 if (sub->module == module) {
7892 listDelNode(moduleKeyspaceSubscribers, ln);
7893 zfree(sub);
7894 }
7895 }
7896}
7897
7898/* --------------------------------------------------------------------------
7899 * ## Modules Cluster API
7900 * -------------------------------------------------------------------------- */
7901
7902/* The Cluster message callback function pointer type. */
7903typedef void (*RedisModuleClusterMessageReceiver)(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len);
7904
7905/* This structure identifies a registered caller: it must match a given module
7906 * ID, for a given message type. The callback function is just the function
7907 * that was registered as receiver. */
7908typedef struct moduleClusterReceiver {
7909 uint64_t module_id;
7910 RedisModuleClusterMessageReceiver callback;
7911 struct RedisModule *module;
7912 struct moduleClusterReceiver *next;
7913} moduleClusterReceiver;
7914
7915typedef struct moduleClusterNodeInfo {
7916 int flags;
7917 char ip[NET_IP_STR_LEN];
7918 int port;
7919 char master_id[40]; /* Only if flags & REDISMODULE_NODE_MASTER is true. */
7920} mdouleClusterNodeInfo;
7921
7922/* We have an array of message types: each bucket is a linked list of
7923 * configured receivers. */
7924static moduleClusterReceiver *clusterReceivers[UINT8_MAX];
7925
7926/* Dispatch the message to the right module receiver. */
7927void moduleCallClusterReceivers(const char *sender_id, uint64_t module_id, uint8_t type, const unsigned char *payload, uint32_t len) {
7928 moduleClusterReceiver *r = clusterReceivers[type];
7929 while(r) {
7930 if (r->module_id == module_id) {
7931 RedisModuleCtx ctx;
7932 moduleCreateContext(&ctx, r->module, REDISMODULE_CTX_TEMP_CLIENT);
7933 selectDb(ctx.client, 0);
7934 r->callback(&ctx,sender_id,type,payload,len);
7935 moduleFreeContext(&ctx);
7936 return;
7937 }
7938 r = r->next;
7939 }
7940}
7941
7942/* Register a callback receiver for cluster messages of type 'type'. If there
7943 * was already a registered callback, this will replace the callback function
7944 * with the one provided, otherwise if the callback is set to NULL and there
7945 * is already a callback for this function, the callback is unregistered
7946 * (so this API call is also used in order to delete the receiver). */
7947void RM_RegisterClusterMessageReceiver(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback) {
7948 if (!server.cluster_enabled) return;
7949
7950 uint64_t module_id = moduleTypeEncodeId(ctx->module->name,0);
7951 moduleClusterReceiver *r = clusterReceivers[type], *prev = NULL;
7952 while(r) {
7953 if (r->module_id == module_id) {
7954 /* Found! Set or delete. */
7955 if (callback) {
7956 r->callback = callback;
7957 } else {
7958 /* Delete the receiver entry if the user is setting
7959 * it to NULL. Just unlink the receiver node from the
7960 * linked list. */
7961 if (prev)
7962 prev->next = r->next;
7963 else
7964 clusterReceivers[type]->next = r->next;
7965 zfree(r);
7966 }
7967 return;
7968 }
7969 prev = r;
7970 r = r->next;
7971 }
7972
7973 /* Not found, let's add it. */
7974 if (callback) {
7975 r = zmalloc(sizeof(*r));
7976 r->module_id = module_id;
7977 r->module = ctx->module;
7978 r->callback = callback;
7979 r->next = clusterReceivers[type];
7980 clusterReceivers[type] = r;
7981 }
7982}
7983
7984/* Send a message to all the nodes in the cluster if `target` is NULL, otherwise
7985 * at the specified target, which is a REDISMODULE_NODE_ID_LEN bytes node ID, as
7986 * returned by the receiver callback or by the nodes iteration functions.
7987 *
7988 * The function returns REDISMODULE_OK if the message was successfully sent,
7989 * otherwise if the node is not connected or such node ID does not map to any
7990 * known cluster node, REDISMODULE_ERR is returned. */
7991int RM_SendClusterMessage(RedisModuleCtx *ctx, const char *target_id, uint8_t type, const char *msg, uint32_t len) {
7992 if (!server.cluster_enabled) return REDISMODULE_ERR;
7993 uint64_t module_id = moduleTypeEncodeId(ctx->module->name,0);
7994 if (clusterSendModuleMessageToTarget(target_id,module_id,type,msg,len) == C_OK)
7995 return REDISMODULE_OK;
7996 else
7997 return REDISMODULE_ERR;
7998}
7999
8000/* Return an array of string pointers, each string pointer points to a cluster
8001 * node ID of exactly REDISMODULE_NODE_ID_LEN bytes (without any null term).
8002 * The number of returned node IDs is stored into `*numnodes`.
8003 * However if this function is called by a module not running an a Redis
8004 * instance with Redis Cluster enabled, NULL is returned instead.
8005 *
8006 * The IDs returned can be used with RedisModule_GetClusterNodeInfo() in order
8007 * to get more information about single node.
8008 *
8009 * The array returned by this function must be freed using the function
8010 * RedisModule_FreeClusterNodesList().
8011 *
8012 * Example:
8013 *
8014 * size_t count, j;
8015 * char **ids = RedisModule_GetClusterNodesList(ctx,&count);
8016 * for (j = 0; j < count; j++) {
8017 * RedisModule_Log(ctx,"notice","Node %.*s",
8018 * REDISMODULE_NODE_ID_LEN,ids[j]);
8019 * }
8020 * RedisModule_FreeClusterNodesList(ids);
8021 */
8022char **RM_GetClusterNodesList(RedisModuleCtx *ctx, size_t *numnodes) {
8023 UNUSED(ctx);
8024
8025 if (!server.cluster_enabled) return NULL;
8026 size_t count = dictSize(server.cluster->nodes);
8027 char **ids = zmalloc((count+1)*REDISMODULE_NODE_ID_LEN);
8028 dictIterator *di = dictGetIterator(server.cluster->nodes);
8029 dictEntry *de;
8030 int j = 0;
8031 while((de = dictNext(di)) != NULL) {
8032 clusterNode *node = dictGetVal(de);
8033 if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) continue;
8034 ids[j] = zmalloc(REDISMODULE_NODE_ID_LEN);
8035 memcpy(ids[j],node->name,REDISMODULE_NODE_ID_LEN);
8036 j++;
8037 }
8038 *numnodes = j;
8039 ids[j] = NULL; /* Null term so that FreeClusterNodesList does not need
8040 * to also get the count argument. */
8041 dictReleaseIterator(di);
8042 return ids;
8043}
8044
8045/* Free the node list obtained with RedisModule_GetClusterNodesList. */
8046void RM_FreeClusterNodesList(char **ids) {
8047 if (ids == NULL) return;
8048 for (int j = 0; ids[j]; j++) zfree(ids[j]);
8049 zfree(ids);
8050}
8051
8052/* Return this node ID (REDISMODULE_CLUSTER_ID_LEN bytes) or NULL if the cluster
8053 * is disabled. */
8054const char *RM_GetMyClusterID(void) {
8055 if (!server.cluster_enabled) return NULL;
8056 return server.cluster->myself->name;
8057}
8058
8059/* Return the number of nodes in the cluster, regardless of their state
8060 * (handshake, noaddress, ...) so that the number of active nodes may actually
8061 * be smaller, but not greater than this number. If the instance is not in
8062 * cluster mode, zero is returned. */
8063size_t RM_GetClusterSize(void) {
8064 if (!server.cluster_enabled) return 0;
8065 return dictSize(server.cluster->nodes);
8066}
8067
8068/* Populate the specified info for the node having as ID the specified 'id',
8069 * then returns REDISMODULE_OK. Otherwise if the format of node ID is invalid
8070 * or the node ID does not exist from the POV of this local node, REDISMODULE_ERR
8071 * is returned.
8072 *
8073 * The arguments `ip`, `master_id`, `port` and `flags` can be NULL in case we don't
8074 * need to populate back certain info. If an `ip` and `master_id` (only populated
8075 * if the instance is a slave) are specified, they point to buffers holding
8076 * at least REDISMODULE_NODE_ID_LEN bytes. The strings written back as `ip`
8077 * and `master_id` are not null terminated.
8078 *
8079 * The list of flags reported is the following:
8080 *
8081 * * REDISMODULE_NODE_MYSELF: This node
8082 * * REDISMODULE_NODE_MASTER: The node is a master
8083 * * REDISMODULE_NODE_SLAVE: The node is a replica
8084 * * REDISMODULE_NODE_PFAIL: We see the node as failing
8085 * * REDISMODULE_NODE_FAIL: The cluster agrees the node is failing
8086 * * REDISMODULE_NODE_NOFAILOVER: The slave is configured to never failover
8087 */
8088int RM_GetClusterNodeInfo(RedisModuleCtx *ctx, const char *id, char *ip, char *master_id, int *port, int *flags) {
8089 UNUSED(ctx);
8090
8091 clusterNode *node = clusterLookupNode(id, strlen(id));
8092 if (node == NULL ||
8093 node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE))
8094 {
8095 return REDISMODULE_ERR;
8096 }
8097
8098 if (ip) strncpy(ip,node->ip,NET_IP_STR_LEN);
8099
8100 if (master_id) {
8101 /* If the information is not available, the function will set the
8102 * field to zero bytes, so that when the field can't be populated the
8103 * function kinda remains predictable. */
8104 if (node->flags & CLUSTER_NODE_SLAVE && node->slaveof)
8105 memcpy(master_id,node->slaveof->name,REDISMODULE_NODE_ID_LEN);
8106 else
8107 memset(master_id,0,REDISMODULE_NODE_ID_LEN);
8108 }
8109 if (port) *port = node->port;
8110
8111 /* As usually we have to remap flags for modules, in order to ensure
8112 * we can provide binary compatibility. */
8113 if (flags) {
8114 *flags = 0;
8115 if (node->flags & CLUSTER_NODE_MYSELF) *flags |= REDISMODULE_NODE_MYSELF;
8116 if (node->flags & CLUSTER_NODE_MASTER) *flags |= REDISMODULE_NODE_MASTER;
8117 if (node->flags & CLUSTER_NODE_SLAVE) *flags |= REDISMODULE_NODE_SLAVE;
8118 if (node->flags & CLUSTER_NODE_PFAIL) *flags |= REDISMODULE_NODE_PFAIL;
8119 if (node->flags & CLUSTER_NODE_FAIL) *flags |= REDISMODULE_NODE_FAIL;
8120 if (node->flags & CLUSTER_NODE_NOFAILOVER) *flags |= REDISMODULE_NODE_NOFAILOVER;
8121 }
8122 return REDISMODULE_OK;
8123}
8124
8125/* Set Redis Cluster flags in order to change the normal behavior of
8126 * Redis Cluster, especially with the goal of disabling certain functions.
8127 * This is useful for modules that use the Cluster API in order to create
8128 * a different distributed system, but still want to use the Redis Cluster
8129 * message bus. Flags that can be set:
8130 *
8131 * * CLUSTER_MODULE_FLAG_NO_FAILOVER
8132 * * CLUSTER_MODULE_FLAG_NO_REDIRECTION
8133 *
8134 * With the following effects:
8135 *
8136 * * NO_FAILOVER: prevent Redis Cluster slaves from failing over a dead master.
8137 * Also disables the replica migration feature.
8138 *
8139 * * NO_REDIRECTION: Every node will accept any key, without trying to perform
8140 * partitioning according to the Redis Cluster algorithm.
8141 * Slots information will still be propagated across the
8142 * cluster, but without effect. */
8143void RM_SetClusterFlags(RedisModuleCtx *ctx, uint64_t flags) {
8144 UNUSED(ctx);
8145 if (flags & REDISMODULE_CLUSTER_FLAG_NO_FAILOVER)
8146 server.cluster_module_flags |= CLUSTER_MODULE_FLAG_NO_FAILOVER;
8147 if (flags & REDISMODULE_CLUSTER_FLAG_NO_REDIRECTION)
8148 server.cluster_module_flags |= CLUSTER_MODULE_FLAG_NO_REDIRECTION;
8149}
8150
8151/* --------------------------------------------------------------------------
8152 * ## Modules Timers API
8153 *
8154 * Module timers are a high precision "green timers" abstraction where
8155 * every module can register even millions of timers without problems, even if
8156 * the actual event loop will just have a single timer that is used to awake the
8157 * module timers subsystem in order to process the next event.
8158 *
8159 * All the timers are stored into a radix tree, ordered by expire time, when
8160 * the main Redis event loop timer callback is called, we try to process all
8161 * the timers already expired one after the other. Then we re-enter the event
8162 * loop registering a timer that will expire when the next to process module
8163 * timer will expire.
8164 *
8165 * Every time the list of active timers drops to zero, we unregister the
8166 * main event loop timer, so that there is no overhead when such feature is
8167 * not used.
8168 * -------------------------------------------------------------------------- */
8169
8170static rax *Timers; /* The radix tree of all the timers sorted by expire. */
8171long long aeTimer = -1; /* Main event loop (ae.c) timer identifier. */
8172
8173typedef void (*RedisModuleTimerProc)(RedisModuleCtx *ctx, void *data);
8174
8175/* The timer descriptor, stored as value in the radix tree. */
8176typedef struct RedisModuleTimer {
8177 RedisModule *module; /* Module reference. */
8178 RedisModuleTimerProc callback; /* The callback to invoke on expire. */
8179 void *data; /* Private data for the callback. */
8180 int dbid; /* Database number selected by the original client. */
8181} RedisModuleTimer;
8182
8183/* This is the timer handler that is called by the main event loop. We schedule
8184 * this timer to be called when the nearest of our module timers will expire. */
8185int moduleTimerHandler(struct aeEventLoop *eventLoop, long long id, void *clientData) {
8186 UNUSED(eventLoop);
8187 UNUSED(id);
8188 UNUSED(clientData);
8189
8190 /* To start let's try to fire all the timers already expired. */
8191 raxIterator ri;
8192 raxStart(&ri,Timers);
8193 uint64_t now = ustime();
8194 long long next_period = 0;
8195 while(1) {
8196 raxSeek(&ri,"^",NULL,0);
8197 if (!raxNext(&ri)) break;
8198 uint64_t expiretime;
8199 memcpy(&expiretime,ri.key,sizeof(expiretime));
8200 expiretime = ntohu64(expiretime);
8201 if (now >= expiretime) {
8202 RedisModuleTimer *timer = ri.data;
8203 RedisModuleCtx ctx;
8204 moduleCreateContext(&ctx,timer->module,REDISMODULE_CTX_TEMP_CLIENT);
8205 selectDb(ctx.client, timer->dbid);
8206 timer->callback(&ctx,timer->data);
8207 moduleFreeContext(&ctx);
8208 raxRemove(Timers,(unsigned char*)ri.key,ri.key_len,NULL);
8209 zfree(timer);
8210 } else {
8211 /* We call ustime() again instead of using the cached 'now' so that
8212 * 'next_period' isn't affected by the time it took to execute
8213 * previous calls to 'callback.
8214 * We need to cast 'expiretime' so that the compiler will not treat
8215 * the difference as unsigned (Causing next_period to be huge) in
8216 * case expiretime < ustime() */
8217 next_period = ((long long)expiretime-ustime())/1000; /* Scale to milliseconds. */
8218 break;
8219 }
8220 }
8221 raxStop(&ri);
8222
8223 /* Reschedule the next timer or cancel it. */
8224 if (next_period <= 0) next_period = 1;
8225 if (raxSize(Timers) > 0) {
8226 return next_period;
8227 } else {
8228 aeTimer = -1;
8229 return AE_NOMORE;
8230 }
8231}
8232
8233/* Create a new timer that will fire after `period` milliseconds, and will call
8234 * the specified function using `data` as argument. The returned timer ID can be
8235 * used to get information from the timer or to stop it before it fires.
8236 * Note that for the common use case of a repeating timer (Re-registration
8237 * of the timer inside the RedisModuleTimerProc callback) it matters when
8238 * this API is called:
8239 * If it is called at the beginning of 'callback' it means
8240 * the event will triggered every 'period'.
8241 * If it is called at the end of 'callback' it means
8242 * there will 'period' milliseconds gaps between events.
8243 * (If the time it takes to execute 'callback' is negligible the two
8244 * statements above mean the same) */
8245RedisModuleTimerID RM_CreateTimer(RedisModuleCtx *ctx, mstime_t period, RedisModuleTimerProc callback, void *data) {
8246 RedisModuleTimer *timer = zmalloc(sizeof(*timer));
8247 timer->module = ctx->module;
8248 timer->callback = callback;
8249 timer->data = data;
8250 timer->dbid = ctx->client ? ctx->client->db->id : 0;
8251 uint64_t expiretime = ustime()+period*1000;
8252 uint64_t key;
8253
8254 while(1) {
8255 key = htonu64(expiretime);
8256 if (raxFind(Timers, (unsigned char*)&key,sizeof(key)) == raxNotFound) {
8257 raxInsert(Timers,(unsigned char*)&key,sizeof(key),timer,NULL);
8258 break;
8259 } else {
8260 expiretime++;
8261 }
8262 }
8263
8264 /* We need to install the main event loop timer if it's not already
8265 * installed, or we may need to refresh its period if we just installed
8266 * a timer that will expire sooner than any other else (i.e. the timer
8267 * we just installed is the first timer in the Timers rax). */
8268 if (aeTimer != -1) {
8269 raxIterator ri;
8270 raxStart(&ri,Timers);
8271 raxSeek(&ri,"^",NULL,0);
8272 raxNext(&ri);
8273 if (memcmp(ri.key,&key,sizeof(key)) == 0) {
8274 /* This is the first key, we need to re-install the timer according
8275 * to the just added event. */
8276 aeDeleteTimeEvent(server.el,aeTimer);
8277 aeTimer = -1;
8278 }
8279 raxStop(&ri);
8280 }
8281
8282 /* If we have no main timer (the old one was invalidated, or this is the
8283 * first module timer we have), install one. */
8284 if (aeTimer == -1)
8285 aeTimer = aeCreateTimeEvent(server.el,period,moduleTimerHandler,NULL,NULL);
8286
8287 return key;
8288}
8289
8290/* Stop a timer, returns REDISMODULE_OK if the timer was found, belonged to the
8291 * calling module, and was stopped, otherwise REDISMODULE_ERR is returned.
8292 * If not NULL, the data pointer is set to the value of the data argument when
8293 * the timer was created. */
8294int RM_StopTimer(RedisModuleCtx *ctx, RedisModuleTimerID id, void **data) {
8295 RedisModuleTimer *timer = raxFind(Timers,(unsigned char*)&id,sizeof(id));
8296 if (timer == raxNotFound || timer->module != ctx->module)
8297 return REDISMODULE_ERR;
8298 if (data) *data = timer->data;
8299 raxRemove(Timers,(unsigned char*)&id,sizeof(id),NULL);
8300 zfree(timer);
8301 return REDISMODULE_OK;
8302}
8303
8304/* Obtain information about a timer: its remaining time before firing
8305 * (in milliseconds), and the private data pointer associated with the timer.
8306 * If the timer specified does not exist or belongs to a different module
8307 * no information is returned and the function returns REDISMODULE_ERR, otherwise
8308 * REDISMODULE_OK is returned. The arguments remaining or data can be NULL if
8309 * the caller does not need certain information. */
8310int RM_GetTimerInfo(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remaining, void **data) {
8311 RedisModuleTimer *timer = raxFind(Timers,(unsigned char*)&id,sizeof(id));
8312 if (timer == raxNotFound || timer->module != ctx->module)
8313 return REDISMODULE_ERR;
8314 if (remaining) {
8315 int64_t rem = ntohu64(id)-ustime();
8316 if (rem < 0) rem = 0;
8317 *remaining = rem/1000; /* Scale to milliseconds. */
8318 }
8319 if (data) *data = timer->data;
8320 return REDISMODULE_OK;
8321}
8322
8323/* Query timers to see if any timer belongs to the module.
8324 * Return 1 if any timer was found, otherwise 0 would be returned. */
8325int moduleHoldsTimer(struct RedisModule *module) {
8326 raxIterator iter;
8327 int found = 0;
8328 raxStart(&iter,Timers);
8329 raxSeek(&iter,"^",NULL,0);
8330 while (raxNext(&iter)) {
8331 RedisModuleTimer *timer = iter.data;
8332 if (timer->module == module) {
8333 found = 1;
8334 break;
8335 }
8336 }
8337 raxStop(&iter);
8338 return found;
8339}
8340
8341/* --------------------------------------------------------------------------
8342 * ## Modules EventLoop API
8343 * --------------------------------------------------------------------------*/
8344
8345typedef struct EventLoopData {
8346 RedisModuleEventLoopFunc rFunc;
8347 RedisModuleEventLoopFunc wFunc;
8348 void *user_data;
8349} EventLoopData;
8350
8351typedef struct EventLoopOneShot {
8352 RedisModuleEventLoopOneShotFunc func;
8353 void *user_data;
8354} EventLoopOneShot;
8355
8356list *moduleEventLoopOneShots;
8357static pthread_mutex_t moduleEventLoopMutex = PTHREAD_MUTEX_INITIALIZER;
8358
8359static int eventLoopToAeMask(int mask) {
8360 int aeMask = 0;
8361 if (mask & REDISMODULE_EVENTLOOP_READABLE)
8362 aeMask |= AE_READABLE;
8363 if (mask & REDISMODULE_EVENTLOOP_WRITABLE)
8364 aeMask |= AE_WRITABLE;
8365 return aeMask;
8366}
8367
8368static int eventLoopFromAeMask(int ae_mask) {
8369 int mask = 0;
8370 if (ae_mask & AE_READABLE)
8371 mask |= REDISMODULE_EVENTLOOP_READABLE;
8372 if (ae_mask & AE_WRITABLE)
8373 mask |= REDISMODULE_EVENTLOOP_WRITABLE;
8374 return mask;
8375}
8376
8377static void eventLoopCbReadable(struct aeEventLoop *ae, int fd, void *user_data, int ae_mask) {
8378 UNUSED(ae);
8379 EventLoopData *data = user_data;
8380 data->rFunc(fd, data->user_data, eventLoopFromAeMask(ae_mask));
8381}
8382
8383static void eventLoopCbWritable(struct aeEventLoop *ae, int fd, void *user_data, int ae_mask) {
8384 UNUSED(ae);
8385 EventLoopData *data = user_data;
8386 data->wFunc(fd, data->user_data, eventLoopFromAeMask(ae_mask));
8387}
8388
8389/* Add a pipe / socket event to the event loop.
8390 *
8391 * * `mask` must be one of the following values:
8392 *
8393 * * `REDISMODULE_EVENTLOOP_READABLE`
8394 * * `REDISMODULE_EVENTLOOP_WRITABLE`
8395 * * `REDISMODULE_EVENTLOOP_READABLE | REDISMODULE_EVENTLOOP_WRITABLE`
8396 *
8397 * On success REDISMODULE_OK is returned, otherwise
8398 * REDISMODULE_ERR is returned and errno is set to the following values:
8399 *
8400 * * ERANGE: `fd` is negative or higher than `maxclients` Redis config.
8401 * * EINVAL: `callback` is NULL or `mask` value is invalid.
8402 *
8403 * `errno` might take other values in case of an internal error.
8404 *
8405 * Example:
8406 *
8407 * void onReadable(int fd, void *user_data, int mask) {
8408 * char buf[32];
8409 * int bytes = read(fd,buf,sizeof(buf));
8410 * printf("Read %d bytes \n", bytes);
8411 * }
8412 * RM_EventLoopAdd(fd, REDISMODULE_EVENTLOOP_READABLE, onReadable, NULL);
8413 */
8414int RM_EventLoopAdd(int fd, int mask, RedisModuleEventLoopFunc func, void *user_data) {
8415 if (fd < 0 || fd >= aeGetSetSize(server.el)) {
8416 errno = ERANGE;
8417 return REDISMODULE_ERR;
8418 }
8419
8420 if (!func || mask & ~(REDISMODULE_EVENTLOOP_READABLE |
8421 REDISMODULE_EVENTLOOP_WRITABLE)) {
8422 errno = EINVAL;
8423 return REDISMODULE_ERR;
8424 }
8425
8426 /* We are going to register stub callbacks to 'ae' for two reasons:
8427 *
8428 * - "ae" callback signature is different from RedisModuleEventLoopCallback,
8429 * that will be handled it in our stub callbacks.
8430 * - We need to remap 'mask' value to provide binary compatibility.
8431 *
8432 * For the stub callbacks, saving user 'callback' and 'user_data' in an
8433 * EventLoopData object and passing it to ae, later, we'll extract
8434 * 'callback' and 'user_data' from that.
8435 */
8436 EventLoopData *data = aeGetFileClientData(server.el, fd);
8437 if (!data)
8438 data = zcalloc(sizeof(*data));
8439
8440 aeFileProc *aeProc;
8441 if (mask & REDISMODULE_EVENTLOOP_READABLE)
8442 aeProc = eventLoopCbReadable;
8443 else
8444 aeProc = eventLoopCbWritable;
8445
8446 int aeMask = eventLoopToAeMask(mask);
8447
8448 if (aeCreateFileEvent(server.el, fd, aeMask, aeProc, data) != AE_OK) {
8449 if (aeGetFileEvents(server.el, fd) == AE_NONE)
8450 zfree(data);
8451 return REDISMODULE_ERR;
8452 }
8453
8454 data->user_data = user_data;
8455 if (mask & REDISMODULE_EVENTLOOP_READABLE)
8456 data->rFunc = func;
8457 if (mask & REDISMODULE_EVENTLOOP_WRITABLE)
8458 data->wFunc = func;
8459
8460 errno = 0;
8461 return REDISMODULE_OK;
8462}
8463
8464/* Delete a pipe / socket event from the event loop.
8465 *
8466 * * `mask` must be one of the following values:
8467 *
8468 * * `REDISMODULE_EVENTLOOP_READABLE`
8469 * * `REDISMODULE_EVENTLOOP_WRITABLE`
8470 * * `REDISMODULE_EVENTLOOP_READABLE | REDISMODULE_EVENTLOOP_WRITABLE`
8471 *
8472 * On success REDISMODULE_OK is returned, otherwise
8473 * REDISMODULE_ERR is returned and errno is set to the following values:
8474 *
8475 * * ERANGE: `fd` is negative or higher than `maxclients` Redis config.
8476 * * EINVAL: `mask` value is invalid.
8477 */
8478int RM_EventLoopDel(int fd, int mask) {
8479 if (fd < 0 || fd >= aeGetSetSize(server.el)) {
8480 errno = ERANGE;
8481 return REDISMODULE_ERR;
8482 }
8483
8484 if (mask & ~(REDISMODULE_EVENTLOOP_READABLE |
8485 REDISMODULE_EVENTLOOP_WRITABLE)) {
8486 errno = EINVAL;
8487 return REDISMODULE_ERR;
8488 }
8489
8490 /* After deleting the event, if fd does not have any registered event
8491 * anymore, we can free the EventLoopData object. */
8492 EventLoopData *data = aeGetFileClientData(server.el, fd);
8493 aeDeleteFileEvent(server.el, fd, eventLoopToAeMask(mask));
8494 if (aeGetFileEvents(server.el, fd) == AE_NONE)
8495 zfree(data);
8496
8497 errno = 0;
8498 return REDISMODULE_OK;
8499}
8500
8501/* This function can be called from other threads to trigger callback on Redis
8502 * main thread. On success REDISMODULE_OK is returned. If `func` is NULL
8503 * REDISMODULE_ERR is returned and errno is set to EINVAL.
8504 */
8505int RM_EventLoopAddOneShot(RedisModuleEventLoopOneShotFunc func, void *user_data) {
8506 if (!func) {
8507 errno = EINVAL;
8508 return REDISMODULE_ERR;
8509 }
8510
8511 EventLoopOneShot *oneshot = zmalloc(sizeof(*oneshot));
8512 oneshot->func = func;
8513 oneshot->user_data = user_data;
8514
8515 pthread_mutex_lock(&moduleEventLoopMutex);
8516 if (!moduleEventLoopOneShots) moduleEventLoopOneShots = listCreate();
8517 listAddNodeTail(moduleEventLoopOneShots, oneshot);
8518 pthread_mutex_unlock(&moduleEventLoopMutex);
8519
8520 if (write(server.module_pipe[1],"A",1) != 1) {
8521 /* Pipe is non-blocking, write() may fail if it's full. */
8522 }
8523
8524 errno = 0;
8525 return REDISMODULE_OK;
8526}
8527
8528/* This function will check the moduleEventLoopOneShots queue in order to
8529 * call the callback for the registered oneshot events. */
8530static void eventLoopHandleOneShotEvents() {
8531 pthread_mutex_lock(&moduleEventLoopMutex);
8532 if (moduleEventLoopOneShots) {
8533 while (listLength(moduleEventLoopOneShots)) {
8534 listNode *ln = listFirst(moduleEventLoopOneShots);
8535 EventLoopOneShot *oneshot = ln->value;
8536 listDelNode(moduleEventLoopOneShots, ln);
8537 /* Unlock mutex before the callback. Another oneshot event can be
8538 * added in the callback, it will need to lock the mutex. */
8539 pthread_mutex_unlock(&moduleEventLoopMutex);
8540 oneshot->func(oneshot->user_data);
8541 zfree(oneshot);
8542 /* Lock again for the next iteration */
8543 pthread_mutex_lock(&moduleEventLoopMutex);
8544 }
8545 }
8546 pthread_mutex_unlock(&moduleEventLoopMutex);
8547}
8548
8549/* --------------------------------------------------------------------------
8550 * ## Modules ACL API
8551 *
8552 * Implements a hook into the authentication and authorization within Redis.
8553 * --------------------------------------------------------------------------*/
8554
8555/* This function is called when a client's user has changed and invokes the
8556 * client's user changed callback if it was set. This callback should
8557 * cleanup any state the module was tracking about this client.
8558 *
8559 * A client's user can be changed through the AUTH command, module
8560 * authentication, and when a client is freed. */
8561void moduleNotifyUserChanged(client *c) {
8562 if (c->auth_callback) {
8563 c->auth_callback(c->id, c->auth_callback_privdata);
8564
8565 /* The callback will fire exactly once, even if the user remains
8566 * the same. It is expected to completely clean up the state
8567 * so all references are cleared here. */
8568 c->auth_callback = NULL;
8569 c->auth_callback_privdata = NULL;
8570 c->auth_module = NULL;
8571 }
8572}
8573
8574void revokeClientAuthentication(client *c) {
8575 /* Freeing the client would result in moduleNotifyUserChanged() to be
8576 * called later, however since we use revokeClientAuthentication() also
8577 * in moduleFreeAuthenticatedClients() to implement module unloading, we
8578 * do this action ASAP: this way if the module is unloaded, when the client
8579 * is eventually freed we don't rely on the module to still exist. */
8580 moduleNotifyUserChanged(c);
8581
8582 c->user = DefaultUser;
8583 c->authenticated = 0;
8584 /* We will write replies to this client later, so we can't close it
8585 * directly even if async. */
8586 if (c == server.current_client) {
8587 c->flags |= CLIENT_CLOSE_AFTER_COMMAND;
8588 } else {
8589 freeClientAsync(c);
8590 }
8591}
8592
8593/* Cleanup all clients that have been authenticated with this module. This
8594 * is called from onUnload() to give the module a chance to cleanup any
8595 * resources associated with clients it has authenticated. */
8596static void moduleFreeAuthenticatedClients(RedisModule *module) {
8597 listIter li;
8598 listNode *ln;
8599 listRewind(server.clients,&li);
8600 while ((ln = listNext(&li)) != NULL) {
8601 client *c = listNodeValue(ln);
8602 if (!c->auth_module) continue;
8603
8604 RedisModule *auth_module = (RedisModule *) c->auth_module;
8605 if (auth_module == module) {
8606 revokeClientAuthentication(c);
8607 }
8608 }
8609}
8610
8611/* Creates a Redis ACL user that the module can use to authenticate a client.
8612 * After obtaining the user, the module should set what such user can do
8613 * using the RM_SetUserACL() function. Once configured, the user
8614 * can be used in order to authenticate a connection, with the specified
8615 * ACL rules, using the RedisModule_AuthClientWithUser() function.
8616 *
8617 * Note that:
8618 *
8619 * * Users created here are not listed by the ACL command.
8620 * * Users created here are not checked for duplicated name, so it's up to
8621 * the module calling this function to take care of not creating users
8622 * with the same name.
8623 * * The created user can be used to authenticate multiple Redis connections.
8624 *
8625 * The caller can later free the user using the function
8626 * RM_FreeModuleUser(). When this function is called, if there are
8627 * still clients authenticated with this user, they are disconnected.
8628 * The function to free the user should only be used when the caller really
8629 * wants to invalidate the user to define a new one with different
8630 * capabilities. */
8631RedisModuleUser *RM_CreateModuleUser(const char *name) {
8632 RedisModuleUser *new_user = zmalloc(sizeof(RedisModuleUser));
8633 new_user->user = ACLCreateUnlinkedUser();
8634 new_user->free_user = 1;
8635
8636 /* Free the previous temporarily assigned name to assign the new one */
8637 sdsfree(new_user->user->name);
8638 new_user->user->name = sdsnew(name);
8639 return new_user;
8640}
8641
8642/* Frees a given user and disconnects all of the clients that have been
8643 * authenticated with it. See RM_CreateModuleUser for detailed usage.*/
8644int RM_FreeModuleUser(RedisModuleUser *user) {
8645 if (user->free_user)
8646 ACLFreeUserAndKillClients(user->user);
8647 zfree(user);
8648 return REDISMODULE_OK;
8649}
8650
8651/* Sets the permissions of a user created through the redis module
8652 * interface. The syntax is the same as ACL SETUSER, so refer to the
8653 * documentation in acl.c for more information. See RM_CreateModuleUser
8654 * for detailed usage.
8655 *
8656 * Returns REDISMODULE_OK on success and REDISMODULE_ERR on failure
8657 * and will set an errno describing why the operation failed. */
8658int RM_SetModuleUserACL(RedisModuleUser *user, const char* acl) {
8659 return ACLSetUser(user->user, acl, -1);
8660}
8661
8662/* Retrieve the user name of the client connection behind the current context.
8663 * The user name can be used later, in order to get a RedisModuleUser.
8664 * See more information in RM_GetModuleUserFromUserName.
8665 *
8666 * The returned string must be released with RedisModule_FreeString() or by
8667 * enabling automatic memory management. */
8668RedisModuleString *RM_GetCurrentUserName(RedisModuleCtx *ctx) {
8669 return RM_CreateString(ctx,ctx->client->user->name,sdslen(ctx->client->user->name));
8670}
8671
8672/* A RedisModuleUser can be used to check if command, key or channel can be executed or
8673 * accessed according to the ACLs rules associated with that user.
8674 * When a Module wants to do ACL checks on a general ACL user (not created by RM_CreateModuleUser),
8675 * it can get the RedisModuleUser from this API, based on the user name retrieved by RM_GetCurrentUserName.
8676 *
8677 * Since a general ACL user can be deleted at any time, this RedisModuleUser should be used only in the context
8678 * where this function was called. In order to do ACL checks out of that context, the Module can store the user name,
8679 * and call this API at any other context.
8680 *
8681 * Returns NULL if the user is disabled or the user does not exist.
8682 * The caller should later free the user using the function RM_FreeModuleUser().*/
8683RedisModuleUser *RM_GetModuleUserFromUserName(RedisModuleString *name) {
8684 /* First, verify that the user exist */
8685 user *acl_user = ACLGetUserByName(name->ptr, sdslen(name->ptr));
8686 if (acl_user == NULL) {
8687 return NULL;
8688 }
8689
8690 RedisModuleUser *new_user = zmalloc(sizeof(RedisModuleUser));
8691 new_user->user = acl_user;
8692 new_user->free_user = 0;
8693 return new_user;
8694}
8695
8696/* Checks if the command can be executed by the user, according to the ACLs associated with it.
8697 *
8698 * On success a REDISMODULE_OK is returned, otherwise
8699 * REDISMODULE_ERR is returned and errno is set to the following values:
8700 *
8701 * * ENOENT: Specified command does not exist.
8702 * * EACCES: Command cannot be executed, according to ACL rules
8703 */
8704int RM_ACLCheckCommandPermissions(RedisModuleUser *user, RedisModuleString **argv, int argc) {
8705 int keyidxptr;
8706 struct redisCommand *cmd;
8707
8708 /* Find command */
8709 if ((cmd = lookupCommand(argv, argc)) == NULL) {
8710 errno = ENOENT;
8711 return REDISMODULE_ERR;
8712 }
8713
8714 if (ACLCheckAllUserCommandPerm(user->user, cmd, argv, argc, &keyidxptr) != ACL_OK) {
8715 errno = EACCES;
8716 return REDISMODULE_ERR;
8717 }
8718
8719 return REDISMODULE_OK;
8720}
8721
8722/* Check if the key can be accessed by the user according to the ACLs attached to the user
8723 * and the flags representing the key access. The flags are the same that are used in the
8724 * keyspec for logical operations. These flags are documented in RedisModule_SetCommandInfo as
8725 * the REDISMODULE_CMD_KEY_ACCESS, REDISMODULE_CMD_KEY_UPDATE, REDISMODULE_CMD_KEY_INSERT,
8726 * and REDISMODULE_CMD_KEY_DELETE flags.
8727 *
8728 * If no flags are supplied, the user is still required to have some access to the key for
8729 * this command to return successfully.
8730 *
8731 * If the user is able to access the key then REDISMODULE_OK is returned, otherwise
8732 * REDISMODULE_ERR is returned and errno is set to one of the following values:
8733 *
8734 * * EINVAL: The provided flags are invalid.
8735 * * EACCESS: The user does not have permission to access the key.
8736 */
8737int RM_ACLCheckKeyPermissions(RedisModuleUser *user, RedisModuleString *key, int flags) {
8738 const int allow_mask = (REDISMODULE_CMD_KEY_ACCESS
8739 | REDISMODULE_CMD_KEY_INSERT
8740 | REDISMODULE_CMD_KEY_DELETE
8741 | REDISMODULE_CMD_KEY_UPDATE);
8742
8743 if ((flags & allow_mask) != flags) {
8744 errno = EINVAL;
8745 return REDISMODULE_ERR;
8746 }
8747
8748 int keyspec_flags = moduleConvertKeySpecsFlags(flags, 0);
8749 if (ACLUserCheckKeyPerm(user->user, key->ptr, sdslen(key->ptr), keyspec_flags) != ACL_OK) {
8750 errno = EACCES;
8751 return REDISMODULE_ERR;
8752 }
8753
8754 return REDISMODULE_OK;
8755}
8756
8757/* Check if the pubsub channel can be accessed by the user based off of the given
8758 * access flags. See RM_ChannelAtPosWithFlags for more information about the
8759 * possible flags that can be passed in.
8760 *
8761 * If the user is able to access the pubsub channel then REDISMODULE_OK is returned, otherwise
8762 * REDISMODULE_ERR is returned and errno is set to one of the following values:
8763 *
8764 * * EINVAL: The provided flags are invalid.
8765 * * EACCESS: The user does not have permission to access the pubsub channel.
8766 */
8767int RM_ACLCheckChannelPermissions(RedisModuleUser *user, RedisModuleString *ch, int flags) {
8768 const int allow_mask = (REDISMODULE_CMD_CHANNEL_PUBLISH
8769 | REDISMODULE_CMD_CHANNEL_SUBSCRIBE
8770 | REDISMODULE_CMD_CHANNEL_UNSUBSCRIBE
8771 | REDISMODULE_CMD_CHANNEL_PATTERN);
8772
8773 if ((flags & allow_mask) != flags) {
8774 errno = EINVAL;
8775 return REDISMODULE_ERR;
8776 }
8777
8778 /* Unsubscribe permissions are currently always allowed. */
8779 if (flags & REDISMODULE_CMD_CHANNEL_UNSUBSCRIBE){
8780 return REDISMODULE_OK;
8781 }
8782
8783 int is_pattern = flags & REDISMODULE_CMD_CHANNEL_PATTERN;
8784 if (ACLUserCheckChannelPerm(user->user, ch->ptr, is_pattern) != ACL_OK)
8785 return REDISMODULE_ERR;
8786
8787 return REDISMODULE_OK;
8788}
8789
8790/* Adds a new entry in the ACL log.
8791 * Returns REDISMODULE_OK on success and REDISMODULE_ERR on error.
8792 *
8793 * For more information about ACL log, please refer to https://redis.io/commands/acl-log */
8794int RM_ACLAddLogEntry(RedisModuleCtx *ctx, RedisModuleUser *user, RedisModuleString *object, RedisModuleACLLogEntryReason reason) {
8795 int acl_reason;
8796 switch (reason) {
8797 case REDISMODULE_ACL_LOG_AUTH: acl_reason = ACL_DENIED_AUTH; break;
8798 case REDISMODULE_ACL_LOG_KEY: acl_reason = ACL_DENIED_KEY; break;
8799 case REDISMODULE_ACL_LOG_CHANNEL: acl_reason = ACL_DENIED_CHANNEL; break;
8800 case REDISMODULE_ACL_LOG_CMD: acl_reason = ACL_DENIED_CMD; break;
8801 default: return REDISMODULE_ERR;
8802 }
8803
8804 addACLLogEntry(ctx->client, acl_reason, ACL_LOG_CTX_MODULE, -1, user->user->name, sdsdup(object->ptr));
8805 return REDISMODULE_OK;
8806}
8807
8808/* Authenticate the client associated with the context with
8809 * the provided user. Returns REDISMODULE_OK on success and
8810 * REDISMODULE_ERR on error.
8811 *
8812 * This authentication can be tracked with the optional callback and private
8813 * data fields. The callback will be called whenever the user of the client
8814 * changes. This callback should be used to cleanup any state that is being
8815 * kept in the module related to the client authentication. It will only be
8816 * called once, even when the user hasn't changed, in order to allow for a
8817 * new callback to be specified. If this authentication does not need to be
8818 * tracked, pass in NULL for the callback and privdata.
8819 *
8820 * If client_id is not NULL, it will be filled with the id of the client
8821 * that was authenticated. This can be used with the
8822 * RM_DeauthenticateAndCloseClient() API in order to deauthenticate a
8823 * previously authenticated client if the authentication is no longer valid.
8824 *
8825 * For expensive authentication operations, it is recommended to block the
8826 * client and do the authentication in the background and then attach the user
8827 * to the client in a threadsafe context. */
8828static int authenticateClientWithUser(RedisModuleCtx *ctx, user *user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
8829 if (user->flags & USER_FLAG_DISABLED) {
8830 return REDISMODULE_ERR;
8831 }
8832
8833 /* Avoid settings which are meaningless and will be lost */
8834 if (!ctx->client || (ctx->client->flags & CLIENT_MODULE)) {
8835 return REDISMODULE_ERR;
8836 }
8837
8838 moduleNotifyUserChanged(ctx->client);
8839
8840 ctx->client->user = user;
8841 ctx->client->authenticated = 1;
8842
8843 if (callback) {
8844 ctx->client->auth_callback = callback;
8845 ctx->client->auth_callback_privdata = privdata;
8846 ctx->client->auth_module = ctx->module;
8847 }
8848
8849 if (client_id) {
8850 *client_id = ctx->client->id;
8851 }
8852
8853 return REDISMODULE_OK;
8854}
8855
8856
8857/* Authenticate the current context's user with the provided redis acl user.
8858 * Returns REDISMODULE_ERR if the user is disabled.
8859 *
8860 * See authenticateClientWithUser for information about callback, client_id,
8861 * and general usage for authentication. */
8862int RM_AuthenticateClientWithUser(RedisModuleCtx *ctx, RedisModuleUser *module_user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
8863 return authenticateClientWithUser(ctx, module_user->user, callback, privdata, client_id);
8864}
8865
8866/* Authenticate the current context's user with the provided redis acl user.
8867 * Returns REDISMODULE_ERR if the user is disabled or the user does not exist.
8868 *
8869 * See authenticateClientWithUser for information about callback, client_id,
8870 * and general usage for authentication. */
8871int RM_AuthenticateClientWithACLUser(RedisModuleCtx *ctx, const char *name, size_t len, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) {
8872 user *acl_user = ACLGetUserByName(name, len);
8873
8874 if (!acl_user) {
8875 return REDISMODULE_ERR;
8876 }
8877 return authenticateClientWithUser(ctx, acl_user, callback, privdata, client_id);
8878}
8879
8880/* Deauthenticate and close the client. The client resources will not be
8881 * immediately freed, but will be cleaned up in a background job. This is
8882 * the recommended way to deauthenticate a client since most clients can't
8883 * handle users becoming deauthenticated. Returns REDISMODULE_ERR when the
8884 * client doesn't exist and REDISMODULE_OK when the operation was successful.
8885 *
8886 * The client ID is returned from the RM_AuthenticateClientWithUser and
8887 * RM_AuthenticateClientWithACLUser APIs, but can be obtained through
8888 * the CLIENT api or through server events.
8889 *
8890 * This function is not thread safe, and must be executed within the context
8891 * of a command or thread safe context. */
8892int RM_DeauthenticateAndCloseClient(RedisModuleCtx *ctx, uint64_t client_id) {
8893 UNUSED(ctx);
8894 client *c = lookupClientByID(client_id);
8895 if (c == NULL) return REDISMODULE_ERR;
8896
8897 /* Revoke also marks client to be closed ASAP */
8898 revokeClientAuthentication(c);
8899 return REDISMODULE_OK;
8900}
8901
8902/* Redact the client command argument specified at the given position. Redacted arguments
8903 * are obfuscated in user facing commands such as SLOWLOG or MONITOR, as well as
8904 * never being written to server logs. This command may be called multiple times on the
8905 * same position.
8906 *
8907 * Note that the command name, position 0, can not be redacted.
8908 *
8909 * Returns REDISMODULE_OK if the argument was redacted and REDISMODULE_ERR if there
8910 * was an invalid parameter passed in or the position is outside the client
8911 * argument range. */
8912int RM_RedactClientCommandArgument(RedisModuleCtx *ctx, int pos) {
8913 if (!ctx || !ctx->client || pos <= 0 || ctx->client->argc <= pos) {
8914 return REDISMODULE_ERR;
8915 }
8916 redactClientCommandArgument(ctx->client, pos);
8917 return REDISMODULE_OK;
8918}
8919
8920/* Return the X.509 client-side certificate used by the client to authenticate
8921 * this connection.
8922 *
8923 * The return value is an allocated RedisModuleString that is a X.509 certificate
8924 * encoded in PEM (Base64) format. It should be freed (or auto-freed) by the caller.
8925 *
8926 * A NULL value is returned in the following conditions:
8927 *
8928 * - Connection ID does not exist
8929 * - Connection is not a TLS connection
8930 * - Connection is a TLS connection but no client certificate was used
8931 */
8932RedisModuleString *RM_GetClientCertificate(RedisModuleCtx *ctx, uint64_t client_id) {
8933 client *c = lookupClientByID(client_id);
8934 if (c == NULL) return NULL;
8935
8936 sds cert = connTLSGetPeerCert(c->conn);
8937 if (!cert) return NULL;
8938
8939 RedisModuleString *s = createObject(OBJ_STRING, cert);
8940 if (ctx != NULL) autoMemoryAdd(ctx, REDISMODULE_AM_STRING, s);
8941
8942 return s;
8943}
8944
8945/* --------------------------------------------------------------------------
8946 * ## Modules Dictionary API
8947 *
8948 * Implements a sorted dictionary (actually backed by a radix tree) with
8949 * the usual get / set / del / num-items API, together with an iterator
8950 * capable of going back and forth.
8951 * -------------------------------------------------------------------------- */
8952
8953/* Create a new dictionary. The 'ctx' pointer can be the current module context
8954 * or NULL, depending on what you want. Please follow the following rules:
8955 *
8956 * 1. Use a NULL context if you plan to retain a reference to this dictionary
8957 * that will survive the time of the module callback where you created it.
8958 * 2. Use a NULL context if no context is available at the time you are creating
8959 * the dictionary (of course...).
8960 * 3. However use the current callback context as 'ctx' argument if the
8961 * dictionary time to live is just limited to the callback scope. In this
8962 * case, if enabled, you can enjoy the automatic memory management that will
8963 * reclaim the dictionary memory, as well as the strings returned by the
8964 * Next / Prev dictionary iterator calls.
8965 */
8966RedisModuleDict *RM_CreateDict(RedisModuleCtx *ctx) {
8967 struct RedisModuleDict *d = zmalloc(sizeof(*d));
8968 d->rax = raxNew();
8969 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_DICT,d);
8970 return d;
8971}
8972
8973/* Free a dictionary created with RM_CreateDict(). You need to pass the
8974 * context pointer 'ctx' only if the dictionary was created using the
8975 * context instead of passing NULL. */
8976void RM_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d) {
8977 if (ctx != NULL) autoMemoryFreed(ctx,REDISMODULE_AM_DICT,d);
8978 raxFree(d->rax);
8979 zfree(d);
8980}
8981
8982/* Return the size of the dictionary (number of keys). */
8983uint64_t RM_DictSize(RedisModuleDict *d) {
8984 return raxSize(d->rax);
8985}
8986
8987/* Store the specified key into the dictionary, setting its value to the
8988 * pointer 'ptr'. If the key was added with success, since it did not
8989 * already exist, REDISMODULE_OK is returned. Otherwise if the key already
8990 * exists the function returns REDISMODULE_ERR. */
8991int RM_DictSetC(RedisModuleDict *d, void *key, size_t keylen, void *ptr) {
8992 int retval = raxTryInsert(d->rax,key,keylen,ptr,NULL);
8993 return (retval == 1) ? REDISMODULE_OK : REDISMODULE_ERR;
8994}
8995
8996/* Like RedisModule_DictSetC() but will replace the key with the new
8997 * value if the key already exists. */
8998int RM_DictReplaceC(RedisModuleDict *d, void *key, size_t keylen, void *ptr) {
8999 int retval = raxInsert(d->rax,key,keylen,ptr,NULL);
9000 return (retval == 1) ? REDISMODULE_OK : REDISMODULE_ERR;
9001}
9002
9003/* Like RedisModule_DictSetC() but takes the key as a RedisModuleString. */
9004int RM_DictSet(RedisModuleDict *d, RedisModuleString *key, void *ptr) {
9005 return RM_DictSetC(d,key->ptr,sdslen(key->ptr),ptr);
9006}
9007
9008/* Like RedisModule_DictReplaceC() but takes the key as a RedisModuleString. */
9009int RM_DictReplace(RedisModuleDict *d, RedisModuleString *key, void *ptr) {
9010 return RM_DictReplaceC(d,key->ptr,sdslen(key->ptr),ptr);
9011}
9012
9013/* Return the value stored at the specified key. The function returns NULL
9014 * both in the case the key does not exist, or if you actually stored
9015 * NULL at key. So, optionally, if the 'nokey' pointer is not NULL, it will
9016 * be set by reference to 1 if the key does not exist, or to 0 if the key
9017 * exists. */
9018void *RM_DictGetC(RedisModuleDict *d, void *key, size_t keylen, int *nokey) {
9019 void *res = raxFind(d->rax,key,keylen);
9020 if (nokey) *nokey = (res == raxNotFound);
9021 return (res == raxNotFound) ? NULL : res;
9022}
9023
9024/* Like RedisModule_DictGetC() but takes the key as a RedisModuleString. */
9025void *RM_DictGet(RedisModuleDict *d, RedisModuleString *key, int *nokey) {
9026 return RM_DictGetC(d,key->ptr,sdslen(key->ptr),nokey);
9027}
9028
9029/* Remove the specified key from the dictionary, returning REDISMODULE_OK if
9030 * the key was found and deleted, or REDISMODULE_ERR if instead there was
9031 * no such key in the dictionary. When the operation is successful, if
9032 * 'oldval' is not NULL, then '*oldval' is set to the value stored at the
9033 * key before it was deleted. Using this feature it is possible to get
9034 * a pointer to the value (for instance in order to release it), without
9035 * having to call RedisModule_DictGet() before deleting the key. */
9036int RM_DictDelC(RedisModuleDict *d, void *key, size_t keylen, void *oldval) {
9037 int retval = raxRemove(d->rax,key,keylen,oldval);
9038 return retval ? REDISMODULE_OK : REDISMODULE_ERR;
9039}
9040
9041/* Like RedisModule_DictDelC() but gets the key as a RedisModuleString. */
9042int RM_DictDel(RedisModuleDict *d, RedisModuleString *key, void *oldval) {
9043 return RM_DictDelC(d,key->ptr,sdslen(key->ptr),oldval);
9044}
9045
9046/* Return an iterator, setup in order to start iterating from the specified
9047 * key by applying the operator 'op', which is just a string specifying the
9048 * comparison operator to use in order to seek the first element. The
9049 * operators available are:
9050 *
9051 * * `^` -- Seek the first (lexicographically smaller) key.
9052 * * `$` -- Seek the last (lexicographically bigger) key.
9053 * * `>` -- Seek the first element greater than the specified key.
9054 * * `>=` -- Seek the first element greater or equal than the specified key.
9055 * * `<` -- Seek the first element smaller than the specified key.
9056 * * `<=` -- Seek the first element smaller or equal than the specified key.
9057 * * `==` -- Seek the first element matching exactly the specified key.
9058 *
9059 * Note that for `^` and `$` the passed key is not used, and the user may
9060 * just pass NULL with a length of 0.
9061 *
9062 * If the element to start the iteration cannot be seeked based on the
9063 * key and operator passed, RedisModule_DictNext() / Prev() will just return
9064 * REDISMODULE_ERR at the first call, otherwise they'll produce elements.
9065 */
9066RedisModuleDictIter *RM_DictIteratorStartC(RedisModuleDict *d, const char *op, void *key, size_t keylen) {
9067 RedisModuleDictIter *di = zmalloc(sizeof(*di));
9068 di->dict = d;
9069 raxStart(&di->ri,d->rax);
9070 raxSeek(&di->ri,op,key,keylen);
9071 return di;
9072}
9073
9074/* Exactly like RedisModule_DictIteratorStartC, but the key is passed as a
9075 * RedisModuleString. */
9076RedisModuleDictIter *RM_DictIteratorStart(RedisModuleDict *d, const char *op, RedisModuleString *key) {
9077 return RM_DictIteratorStartC(d,op,key->ptr,sdslen(key->ptr));
9078}
9079
9080/* Release the iterator created with RedisModule_DictIteratorStart(). This call
9081 * is mandatory otherwise a memory leak is introduced in the module. */
9082void RM_DictIteratorStop(RedisModuleDictIter *di) {
9083 raxStop(&di->ri);
9084 zfree(di);
9085}
9086
9087/* After its creation with RedisModule_DictIteratorStart(), it is possible to
9088 * change the currently selected element of the iterator by using this
9089 * API call. The result based on the operator and key is exactly like
9090 * the function RedisModule_DictIteratorStart(), however in this case the
9091 * return value is just REDISMODULE_OK in case the seeked element was found,
9092 * or REDISMODULE_ERR in case it was not possible to seek the specified
9093 * element. It is possible to reseek an iterator as many times as you want. */
9094int RM_DictIteratorReseekC(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) {
9095 return raxSeek(&di->ri,op,key,keylen);
9096}
9097
9098/* Like RedisModule_DictIteratorReseekC() but takes the key as a
9099 * RedisModuleString. */
9100int RM_DictIteratorReseek(RedisModuleDictIter *di, const char *op, RedisModuleString *key) {
9101 return RM_DictIteratorReseekC(di,op,key->ptr,sdslen(key->ptr));
9102}
9103
9104/* Return the current item of the dictionary iterator `di` and steps to the
9105 * next element. If the iterator already yield the last element and there
9106 * are no other elements to return, NULL is returned, otherwise a pointer
9107 * to a string representing the key is provided, and the `*keylen` length
9108 * is set by reference (if keylen is not NULL). The `*dataptr`, if not NULL
9109 * is set to the value of the pointer stored at the returned key as auxiliary
9110 * data (as set by the RedisModule_DictSet API).
9111 *
9112 * Usage example:
9113 *
9114 * ... create the iterator here ...
9115 * char *key;
9116 * void *data;
9117 * while((key = RedisModule_DictNextC(iter,&keylen,&data)) != NULL) {
9118 * printf("%.*s %p\n", (int)keylen, key, data);
9119 * }
9120 *
9121 * The returned pointer is of type void because sometimes it makes sense
9122 * to cast it to a `char*` sometimes to an unsigned `char*` depending on the
9123 * fact it contains or not binary data, so this API ends being more
9124 * comfortable to use.
9125 *
9126 * The validity of the returned pointer is until the next call to the
9127 * next/prev iterator step. Also the pointer is no longer valid once the
9128 * iterator is released. */
9129void *RM_DictNextC(RedisModuleDictIter *di, size_t *keylen, void **dataptr) {
9130 if (!raxNext(&di->ri)) return NULL;
9131 if (keylen) *keylen = di->ri.key_len;
9132 if (dataptr) *dataptr = di->ri.data;
9133 return di->ri.key;
9134}
9135
9136/* This function is exactly like RedisModule_DictNext() but after returning
9137 * the currently selected element in the iterator, it selects the previous
9138 * element (lexicographically smaller) instead of the next one. */
9139void *RM_DictPrevC(RedisModuleDictIter *di, size_t *keylen, void **dataptr) {
9140 if (!raxPrev(&di->ri)) return NULL;
9141 if (keylen) *keylen = di->ri.key_len;
9142 if (dataptr) *dataptr = di->ri.data;
9143 return di->ri.key;
9144}
9145
9146/* Like RedisModuleNextC(), but instead of returning an internally allocated
9147 * buffer and key length, it returns directly a module string object allocated
9148 * in the specified context 'ctx' (that may be NULL exactly like for the main
9149 * API RedisModule_CreateString).
9150 *
9151 * The returned string object should be deallocated after use, either manually
9152 * or by using a context that has automatic memory management active. */
9153RedisModuleString *RM_DictNext(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr) {
9154 size_t keylen;
9155 void *key = RM_DictNextC(di,&keylen,dataptr);
9156 if (key == NULL) return NULL;
9157 return RM_CreateString(ctx,key,keylen);
9158}
9159
9160/* Like RedisModule_DictNext() but after returning the currently selected
9161 * element in the iterator, it selects the previous element (lexicographically
9162 * smaller) instead of the next one. */
9163RedisModuleString *RM_DictPrev(RedisModuleCtx *ctx, RedisModuleDictIter *di, void **dataptr) {
9164 size_t keylen;
9165 void *key = RM_DictPrevC(di,&keylen,dataptr);
9166 if (key == NULL) return NULL;
9167 return RM_CreateString(ctx,key,keylen);
9168}
9169
9170/* Compare the element currently pointed by the iterator to the specified
9171 * element given by key/keylen, according to the operator 'op' (the set of
9172 * valid operators are the same valid for RedisModule_DictIteratorStart).
9173 * If the comparison is successful the command returns REDISMODULE_OK
9174 * otherwise REDISMODULE_ERR is returned.
9175 *
9176 * This is useful when we want to just emit a lexicographical range, so
9177 * in the loop, as we iterate elements, we can also check if we are still
9178 * on range.
9179 *
9180 * The function return REDISMODULE_ERR if the iterator reached the
9181 * end of elements condition as well. */
9182int RM_DictCompareC(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) {
9183 if (raxEOF(&di->ri)) return REDISMODULE_ERR;
9184 int res = raxCompare(&di->ri,op,key,keylen);
9185 return res ? REDISMODULE_OK : REDISMODULE_ERR;
9186}
9187
9188/* Like RedisModule_DictCompareC but gets the key to compare with the current
9189 * iterator key as a RedisModuleString. */
9190int RM_DictCompare(RedisModuleDictIter *di, const char *op, RedisModuleString *key) {
9191 if (raxEOF(&di->ri)) return REDISMODULE_ERR;
9192 int res = raxCompare(&di->ri,op,key->ptr,sdslen(key->ptr));
9193 return res ? REDISMODULE_OK : REDISMODULE_ERR;
9194}
9195
9196
9197
9198
9199/* --------------------------------------------------------------------------
9200 * ## Modules Info fields
9201 * -------------------------------------------------------------------------- */
9202
9203int RM_InfoEndDictField(RedisModuleInfoCtx *ctx);
9204
9205/* Used to start a new section, before adding any fields. the section name will
9206 * be prefixed by `<modulename>_` and must only include A-Z,a-z,0-9.
9207 * NULL or empty string indicates the default section (only `<modulename>`) is used.
9208 * When return value is REDISMODULE_ERR, the section should and will be skipped. */
9209int RM_InfoAddSection(RedisModuleInfoCtx *ctx, const char *name) {
9210 sds full_name = sdsdup(ctx->module->name);
9211 if (name != NULL && strlen(name) > 0)
9212 full_name = sdscatfmt(full_name, "_%s", name);
9213
9214 /* Implicitly end dicts, instead of returning an error which is likely un checked. */
9215 if (ctx->in_dict_field)
9216 RM_InfoEndDictField(ctx);
9217
9218 /* proceed only if:
9219 * 1) no section was requested (emit all)
9220 * 2) the module name was requested (emit all)
9221 * 3) this specific section was requested. */
9222 if (ctx->requested_sections) {
9223 if ((!full_name || !dictFind(ctx->requested_sections, full_name)) &&
9224 (!dictFind(ctx->requested_sections, ctx->module->name)))
9225 {
9226 sdsfree(full_name);
9227 ctx->in_section = 0;
9228 return REDISMODULE_ERR;
9229 }
9230 }
9231 if (ctx->sections++) ctx->info = sdscat(ctx->info,"\r\n");
9232 ctx->info = sdscatfmt(ctx->info, "# %S\r\n", full_name);
9233 ctx->in_section = 1;
9234 sdsfree(full_name);
9235 return REDISMODULE_OK;
9236}
9237
9238/* Starts a dict field, similar to the ones in INFO KEYSPACE. Use normal
9239 * RedisModule_InfoAddField* functions to add the items to this field, and
9240 * terminate with RedisModule_InfoEndDictField. */
9241int RM_InfoBeginDictField(RedisModuleInfoCtx *ctx, const char *name) {
9242 if (!ctx->in_section)
9243 return REDISMODULE_ERR;
9244 /* Implicitly end dicts, instead of returning an error which is likely un checked. */
9245 if (ctx->in_dict_field)
9246 RM_InfoEndDictField(ctx);
9247 char *tmpmodname, *tmpname;
9248 ctx->info = sdscatfmt(ctx->info,
9249 "%s_%s:",
9250 getSafeInfoString(ctx->module->name, strlen(ctx->module->name), &tmpmodname),
9251 getSafeInfoString(name, strlen(name), &tmpname));
9252 if (tmpmodname != NULL) zfree(tmpmodname);
9253 if (tmpname != NULL) zfree(tmpname);
9254 ctx->in_dict_field = 1;
9255 return REDISMODULE_OK;
9256}
9257
9258/* Ends a dict field, see RedisModule_InfoBeginDictField */
9259int RM_InfoEndDictField(RedisModuleInfoCtx *ctx) {
9260 if (!ctx->in_dict_field)
9261 return REDISMODULE_ERR;
9262 /* trim the last ',' if found. */
9263 if (ctx->info[sdslen(ctx->info)-1]==',')
9264 sdsIncrLen(ctx->info, -1);
9265 ctx->info = sdscat(ctx->info, "\r\n");
9266 ctx->in_dict_field = 0;
9267 return REDISMODULE_OK;
9268}
9269
9270/* Used by RedisModuleInfoFunc to add info fields.
9271 * Each field will be automatically prefixed by `<modulename>_`.
9272 * Field names or values must not include `\r\n` or `:`. */
9273int RM_InfoAddFieldString(RedisModuleInfoCtx *ctx, const char *field, RedisModuleString *value) {
9274 if (!ctx->in_section)
9275 return REDISMODULE_ERR;
9276 if (ctx->in_dict_field) {
9277 ctx->info = sdscatfmt(ctx->info,
9278 "%s=%S,",
9279 field,
9280 (sds)value->ptr);
9281 return REDISMODULE_OK;
9282 }
9283 ctx->info = sdscatfmt(ctx->info,
9284 "%s_%s:%S\r\n",
9285 ctx->module->name,
9286 field,
9287 (sds)value->ptr);
9288 return REDISMODULE_OK;
9289}
9290
9291/* See RedisModule_InfoAddFieldString(). */
9292int RM_InfoAddFieldCString(RedisModuleInfoCtx *ctx, const char *field, const char *value) {
9293 if (!ctx->in_section)
9294 return REDISMODULE_ERR;
9295 if (ctx->in_dict_field) {
9296 ctx->info = sdscatfmt(ctx->info,
9297 "%s=%s,",
9298 field,
9299 value);
9300 return REDISMODULE_OK;
9301 }
9302 ctx->info = sdscatfmt(ctx->info,
9303 "%s_%s:%s\r\n",
9304 ctx->module->name,
9305 field,
9306 value);
9307 return REDISMODULE_OK;
9308}
9309
9310/* See RedisModule_InfoAddFieldString(). */
9311int RM_InfoAddFieldDouble(RedisModuleInfoCtx *ctx, const char *field, double value) {
9312 if (!ctx->in_section)
9313 return REDISMODULE_ERR;
9314 if (ctx->in_dict_field) {
9315 ctx->info = sdscatprintf(ctx->info,
9316 "%s=%.17g,",
9317 field,
9318 value);
9319 return REDISMODULE_OK;
9320 }
9321 ctx->info = sdscatprintf(ctx->info,
9322 "%s_%s:%.17g\r\n",
9323 ctx->module->name,
9324 field,
9325 value);
9326 return REDISMODULE_OK;
9327}
9328
9329/* See RedisModule_InfoAddFieldString(). */
9330int RM_InfoAddFieldLongLong(RedisModuleInfoCtx *ctx, const char *field, long long value) {
9331 if (!ctx->in_section)
9332 return REDISMODULE_ERR;
9333 if (ctx->in_dict_field) {
9334 ctx->info = sdscatfmt(ctx->info,
9335 "%s=%I,",
9336 field,
9337 value);
9338 return REDISMODULE_OK;
9339 }
9340 ctx->info = sdscatfmt(ctx->info,
9341 "%s_%s:%I\r\n",
9342 ctx->module->name,
9343 field,
9344 value);
9345 return REDISMODULE_OK;
9346}
9347
9348/* See RedisModule_InfoAddFieldString(). */
9349int RM_InfoAddFieldULongLong(RedisModuleInfoCtx *ctx, const char *field, unsigned long long value) {
9350 if (!ctx->in_section)
9351 return REDISMODULE_ERR;
9352 if (ctx->in_dict_field) {
9353 ctx->info = sdscatfmt(ctx->info,
9354 "%s=%U,",
9355 field,
9356 value);
9357 return REDISMODULE_OK;
9358 }
9359 ctx->info = sdscatfmt(ctx->info,
9360 "%s_%s:%U\r\n",
9361 ctx->module->name,
9362 field,
9363 value);
9364 return REDISMODULE_OK;
9365}
9366
9367/* Registers callback for the INFO command. The callback should add INFO fields
9368 * by calling the `RedisModule_InfoAddField*()` functions. */
9369int RM_RegisterInfoFunc(RedisModuleCtx *ctx, RedisModuleInfoFunc cb) {
9370 ctx->module->info_cb = cb;
9371 return REDISMODULE_OK;
9372}
9373
9374sds modulesCollectInfo(sds info, dict *sections_dict, int for_crash_report, int sections) {
9375 dictIterator *di = dictGetIterator(modules);
9376 dictEntry *de;
9377
9378 while ((de = dictNext(di)) != NULL) {
9379 struct RedisModule *module = dictGetVal(de);
9380 if (!module->info_cb)
9381 continue;
9382 RedisModuleInfoCtx info_ctx = {module, sections_dict, info, sections, 0, 0};
9383 module->info_cb(&info_ctx, for_crash_report);
9384 /* Implicitly end dicts (no way to handle errors, and we must add the newline). */
9385 if (info_ctx.in_dict_field)
9386 RM_InfoEndDictField(&info_ctx);
9387 info = info_ctx.info;
9388 sections = info_ctx.sections;
9389 }
9390 dictReleaseIterator(di);
9391 return info;
9392}
9393
9394/* Get information about the server similar to the one that returns from the
9395 * INFO command. This function takes an optional 'section' argument that may
9396 * be NULL. The return value holds the output and can be used with
9397 * RedisModule_ServerInfoGetField and alike to get the individual fields.
9398 * When done, it needs to be freed with RedisModule_FreeServerInfo or with the
9399 * automatic memory management mechanism if enabled. */
9400RedisModuleServerInfoData *RM_GetServerInfo(RedisModuleCtx *ctx, const char *section) {
9401 struct RedisModuleServerInfoData *d = zmalloc(sizeof(*d));
9402 d->rax = raxNew();
9403 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_INFO,d);
9404 int all = 0, everything = 0;
9405 robj *argv[1];
9406 argv[0] = section ? createStringObject(section, strlen(section)) : NULL;
9407 dict *section_dict = genInfoSectionDict(argv, section ? 1 : 0, NULL, &all, &everything);
9408 sds info = genRedisInfoString(section_dict, all, everything);
9409 int totlines, i;
9410 sds *lines = sdssplitlen(info, sdslen(info), "\r\n", 2, &totlines);
9411 for(i=0; i<totlines; i++) {
9412 sds line = lines[i];
9413 if (line[0]=='#') continue;
9414 char *sep = strchr(line, ':');
9415 if (!sep) continue;
9416 unsigned char *key = (unsigned char*)line;
9417 size_t keylen = (intptr_t)sep-(intptr_t)line;
9418 sds val = sdsnewlen(sep+1,sdslen(line)-((intptr_t)sep-(intptr_t)line)-1);
9419 if (!raxTryInsert(d->rax,key,keylen,val,NULL))
9420 sdsfree(val);
9421 }
9422 sdsfree(info);
9423 sdsfreesplitres(lines,totlines);
9424 releaseInfoSectionDict(section_dict);
9425 if(argv[0]) decrRefCount(argv[0]);
9426 return d;
9427}
9428
9429/* Free data created with RM_GetServerInfo(). You need to pass the
9430 * context pointer 'ctx' only if the dictionary was created using the
9431 * context instead of passing NULL. */
9432void RM_FreeServerInfo(RedisModuleCtx *ctx, RedisModuleServerInfoData *data) {
9433 if (ctx != NULL) autoMemoryFreed(ctx,REDISMODULE_AM_INFO,data);
9434 raxFreeWithCallback(data->rax, (void(*)(void*))sdsfree);
9435 zfree(data);
9436}
9437
9438/* Get the value of a field from data collected with RM_GetServerInfo(). You
9439 * need to pass the context pointer 'ctx' only if you want to use auto memory
9440 * mechanism to release the returned string. Return value will be NULL if the
9441 * field was not found. */
9442RedisModuleString *RM_ServerInfoGetField(RedisModuleCtx *ctx, RedisModuleServerInfoData *data, const char* field) {
9443 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
9444 if (val == raxNotFound) return NULL;
9445 RedisModuleString *o = createStringObject(val,sdslen(val));
9446 if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
9447 return o;
9448}
9449
9450/* Similar to RM_ServerInfoGetField, but returns a char* which should not be freed but the caller. */
9451const char *RM_ServerInfoGetFieldC(RedisModuleServerInfoData *data, const char* field) {
9452 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
9453 if (val == raxNotFound) return NULL;
9454 return val;
9455}
9456
9457/* Get the value of a field from data collected with RM_GetServerInfo(). If the
9458 * field is not found, or is not numerical or out of range, return value will be
9459 * 0, and the optional out_err argument will be set to REDISMODULE_ERR. */
9460long long RM_ServerInfoGetFieldSigned(RedisModuleServerInfoData *data, const char* field, int *out_err) {
9461 long long ll;
9462 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
9463 if (val == raxNotFound) {
9464 if (out_err) *out_err = REDISMODULE_ERR;
9465 return 0;
9466 }
9467 if (!string2ll(val,sdslen(val),&ll)) {
9468 if (out_err) *out_err = REDISMODULE_ERR;
9469 return 0;
9470 }
9471 if (out_err) *out_err = REDISMODULE_OK;
9472 return ll;
9473}
9474
9475/* Get the value of a field from data collected with RM_GetServerInfo(). If the
9476 * field is not found, or is not numerical or out of range, return value will be
9477 * 0, and the optional out_err argument will be set to REDISMODULE_ERR. */
9478unsigned long long RM_ServerInfoGetFieldUnsigned(RedisModuleServerInfoData *data, const char* field, int *out_err) {
9479 unsigned long long ll;
9480 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
9481 if (val == raxNotFound) {
9482 if (out_err) *out_err = REDISMODULE_ERR;
9483 return 0;
9484 }
9485 if (!string2ull(val,&ll)) {
9486 if (out_err) *out_err = REDISMODULE_ERR;
9487 return 0;
9488 }
9489 if (out_err) *out_err = REDISMODULE_OK;
9490 return ll;
9491}
9492
9493/* Get the value of a field from data collected with RM_GetServerInfo(). If the
9494 * field is not found, or is not a double, return value will be 0, and the
9495 * optional out_err argument will be set to REDISMODULE_ERR. */
9496double RM_ServerInfoGetFieldDouble(RedisModuleServerInfoData *data, const char* field, int *out_err) {
9497 double dbl;
9498 sds val = raxFind(data->rax, (unsigned char *)field, strlen(field));
9499 if (val == raxNotFound) {
9500 if (out_err) *out_err = REDISMODULE_ERR;
9501 return 0;
9502 }
9503 if (!string2d(val,sdslen(val),&dbl)) {
9504 if (out_err) *out_err = REDISMODULE_ERR;
9505 return 0;
9506 }
9507 if (out_err) *out_err = REDISMODULE_OK;
9508 return dbl;
9509}
9510
9511/* --------------------------------------------------------------------------
9512 * ## Modules utility APIs
9513 * -------------------------------------------------------------------------- */
9514
9515/* Return random bytes using SHA1 in counter mode with a /dev/urandom
9516 * initialized seed. This function is fast so can be used to generate
9517 * many bytes without any effect on the operating system entropy pool.
9518 * Currently this function is not thread safe. */
9519void RM_GetRandomBytes(unsigned char *dst, size_t len) {
9520 getRandomBytes(dst,len);
9521}
9522
9523/* Like RedisModule_GetRandomBytes() but instead of setting the string to
9524 * random bytes the string is set to random characters in the in the
9525 * hex charset [0-9a-f]. */
9526void RM_GetRandomHexChars(char *dst, size_t len) {
9527 getRandomHexChars(dst,len);
9528}
9529
9530/* --------------------------------------------------------------------------
9531 * ## Modules API exporting / importing
9532 * -------------------------------------------------------------------------- */
9533
9534/* This function is called by a module in order to export some API with a
9535 * given name. Other modules will be able to use this API by calling the
9536 * symmetrical function RM_GetSharedAPI() and casting the return value to
9537 * the right function pointer.
9538 *
9539 * The function will return REDISMODULE_OK if the name is not already taken,
9540 * otherwise REDISMODULE_ERR will be returned and no operation will be
9541 * performed.
9542 *
9543 * IMPORTANT: the apiname argument should be a string literal with static
9544 * lifetime. The API relies on the fact that it will always be valid in
9545 * the future. */
9546int RM_ExportSharedAPI(RedisModuleCtx *ctx, const char *apiname, void *func) {
9547 RedisModuleSharedAPI *sapi = zmalloc(sizeof(*sapi));
9548 sapi->module = ctx->module;
9549 sapi->func = func;
9550 if (dictAdd(server.sharedapi, (char*)apiname, sapi) != DICT_OK) {
9551 zfree(sapi);
9552 return REDISMODULE_ERR;
9553 }
9554 return REDISMODULE_OK;
9555}
9556
9557/* Request an exported API pointer. The return value is just a void pointer
9558 * that the caller of this function will be required to cast to the right
9559 * function pointer, so this is a private contract between modules.
9560 *
9561 * If the requested API is not available then NULL is returned. Because
9562 * modules can be loaded at different times with different order, this
9563 * function calls should be put inside some module generic API registering
9564 * step, that is called every time a module attempts to execute a
9565 * command that requires external APIs: if some API cannot be resolved, the
9566 * command should return an error.
9567 *
9568 * Here is an example:
9569 *
9570 * int ... myCommandImplementation() {
9571 * if (getExternalAPIs() == 0) {
9572 * reply with an error here if we cannot have the APIs
9573 * }
9574 * // Use the API:
9575 * myFunctionPointer(foo);
9576 * }
9577 *
9578 * And the function registerAPI() is:
9579 *
9580 * int getExternalAPIs(void) {
9581 * static int api_loaded = 0;
9582 * if (api_loaded != 0) return 1; // APIs already resolved.
9583 *
9584 * myFunctionPointer = RedisModule_GetOtherModuleAPI("...");
9585 * if (myFunctionPointer == NULL) return 0;
9586 *
9587 * return 1;
9588 * }
9589 */
9590void *RM_GetSharedAPI(RedisModuleCtx *ctx, const char *apiname) {
9591 dictEntry *de = dictFind(server.sharedapi, apiname);
9592 if (de == NULL) return NULL;
9593 RedisModuleSharedAPI *sapi = dictGetVal(de);
9594 if (listSearchKey(sapi->module->usedby,ctx->module) == NULL) {
9595 listAddNodeTail(sapi->module->usedby,ctx->module);
9596 listAddNodeTail(ctx->module->using,sapi->module);
9597 }
9598 return sapi->func;
9599}
9600
9601/* Remove all the APIs registered by the specified module. Usually you
9602 * want this when the module is going to be unloaded. This function
9603 * assumes that's caller responsibility to make sure the APIs are not
9604 * used by other modules.
9605 *
9606 * The number of unregistered APIs is returned. */
9607int moduleUnregisterSharedAPI(RedisModule *module) {
9608 int count = 0;
9609 dictIterator *di = dictGetSafeIterator(server.sharedapi);
9610 dictEntry *de;
9611 while ((de = dictNext(di)) != NULL) {
9612 const char *apiname = dictGetKey(de);
9613 RedisModuleSharedAPI *sapi = dictGetVal(de);
9614 if (sapi->module == module) {
9615 dictDelete(server.sharedapi,apiname);
9616 zfree(sapi);
9617 count++;
9618 }
9619 }
9620 dictReleaseIterator(di);
9621 return count;
9622}
9623
9624/* Remove the specified module as an user of APIs of ever other module.
9625 * This is usually called when a module is unloaded.
9626 *
9627 * Returns the number of modules this module was using APIs from. */
9628int moduleUnregisterUsedAPI(RedisModule *module) {
9629 listIter li;
9630 listNode *ln;
9631 int count = 0;
9632
9633 listRewind(module->using,&li);
9634 while((ln = listNext(&li))) {
9635 RedisModule *used = ln->value;
9636 listNode *ln = listSearchKey(used->usedby,module);
9637 if (ln) {
9638 listDelNode(used->usedby,ln);
9639 count++;
9640 }
9641 }
9642 return count;
9643}
9644
9645/* Unregister all filters registered by a module.
9646 * This is called when a module is being unloaded.
9647 *
9648 * Returns the number of filters unregistered. */
9649int moduleUnregisterFilters(RedisModule *module) {
9650 listIter li;
9651 listNode *ln;
9652 int count = 0;
9653
9654 listRewind(module->filters,&li);
9655 while((ln = listNext(&li))) {
9656 RedisModuleCommandFilter *filter = ln->value;
9657 listNode *ln = listSearchKey(moduleCommandFilters,filter);
9658 if (ln) {
9659 listDelNode(moduleCommandFilters,ln);
9660 count++;
9661 }
9662 zfree(filter);
9663 }
9664 return count;
9665}
9666
9667/* --------------------------------------------------------------------------
9668 * ## Module Command Filter API
9669 * -------------------------------------------------------------------------- */
9670
9671/* Register a new command filter function.
9672 *
9673 * Command filtering makes it possible for modules to extend Redis by plugging
9674 * into the execution flow of all commands.
9675 *
9676 * A registered filter gets called before Redis executes *any* command. This
9677 * includes both core Redis commands and commands registered by any module. The
9678 * filter applies in all execution paths including:
9679 *
9680 * 1. Invocation by a client.
9681 * 2. Invocation through `RedisModule_Call()` by any module.
9682 * 3. Invocation through Lua `redis.call()`.
9683 * 4. Replication of a command from a master.
9684 *
9685 * The filter executes in a special filter context, which is different and more
9686 * limited than a RedisModuleCtx. Because the filter affects any command, it
9687 * must be implemented in a very efficient way to reduce the performance impact
9688 * on Redis. All Redis Module API calls that require a valid context (such as
9689 * `RedisModule_Call()`, `RedisModule_OpenKey()`, etc.) are not supported in a
9690 * filter context.
9691 *
9692 * The `RedisModuleCommandFilterCtx` can be used to inspect or modify the
9693 * executed command and its arguments. As the filter executes before Redis
9694 * begins processing the command, any change will affect the way the command is
9695 * processed. For example, a module can override Redis commands this way:
9696 *
9697 * 1. Register a `MODULE.SET` command which implements an extended version of
9698 * the Redis `SET` command.
9699 * 2. Register a command filter which detects invocation of `SET` on a specific
9700 * pattern of keys. Once detected, the filter will replace the first
9701 * argument from `SET` to `MODULE.SET`.
9702 * 3. When filter execution is complete, Redis considers the new command name
9703 * and therefore executes the module's own command.
9704 *
9705 * Note that in the above use case, if `MODULE.SET` itself uses
9706 * `RedisModule_Call()` the filter will be applied on that call as well. If
9707 * that is not desired, the `REDISMODULE_CMDFILTER_NOSELF` flag can be set when
9708 * registering the filter.
9709 *
9710 * The `REDISMODULE_CMDFILTER_NOSELF` flag prevents execution flows that
9711 * originate from the module's own `RM_Call()` from reaching the filter. This
9712 * flag is effective for all execution flows, including nested ones, as long as
9713 * the execution begins from the module's command context or a thread-safe
9714 * context that is associated with a blocking command.
9715 *
9716 * Detached thread-safe contexts are *not* associated with the module and cannot
9717 * be protected by this flag.
9718 *
9719 * If multiple filters are registered (by the same or different modules), they
9720 * are executed in the order of registration.
9721 */
9722RedisModuleCommandFilter *RM_RegisterCommandFilter(RedisModuleCtx *ctx, RedisModuleCommandFilterFunc callback, int flags) {
9723 RedisModuleCommandFilter *filter = zmalloc(sizeof(*filter));
9724 filter->module = ctx->module;
9725 filter->callback = callback;
9726 filter->flags = flags;
9727
9728 listAddNodeTail(moduleCommandFilters, filter);
9729 listAddNodeTail(ctx->module->filters, filter);
9730 return filter;
9731}
9732
9733/* Unregister a command filter.
9734 */
9735int RM_UnregisterCommandFilter(RedisModuleCtx *ctx, RedisModuleCommandFilter *filter) {
9736 listNode *ln;
9737
9738 /* A module can only remove its own filters */
9739 if (filter->module != ctx->module) return REDISMODULE_ERR;
9740
9741 ln = listSearchKey(moduleCommandFilters,filter);
9742 if (!ln) return REDISMODULE_ERR;
9743 listDelNode(moduleCommandFilters,ln);
9744
9745 ln = listSearchKey(ctx->module->filters,filter);
9746 if (!ln) return REDISMODULE_ERR; /* Shouldn't happen */
9747 listDelNode(ctx->module->filters,ln);
9748
9749 zfree(filter);
9750
9751 return REDISMODULE_OK;
9752}
9753
9754void moduleCallCommandFilters(client *c) {
9755 if (listLength(moduleCommandFilters) == 0) return;
9756
9757 listIter li;
9758 listNode *ln;
9759 listRewind(moduleCommandFilters,&li);
9760
9761 RedisModuleCommandFilterCtx filter = {
9762 .argv = c->argv,
9763 .argc = c->argc
9764 };
9765
9766 while((ln = listNext(&li))) {
9767 RedisModuleCommandFilter *f = ln->value;
9768
9769 /* Skip filter if REDISMODULE_CMDFILTER_NOSELF is set and module is
9770 * currently processing a command.
9771 */
9772 if ((f->flags & REDISMODULE_CMDFILTER_NOSELF) && f->module->in_call) continue;
9773
9774 /* Call filter */
9775 f->callback(&filter);
9776 }
9777
9778 c->argv = filter.argv;
9779 c->argc = filter.argc;
9780}
9781
9782/* Return the number of arguments a filtered command has. The number of
9783 * arguments include the command itself.
9784 */
9785int RM_CommandFilterArgsCount(RedisModuleCommandFilterCtx *fctx)
9786{
9787 return fctx->argc;
9788}
9789
9790/* Return the specified command argument. The first argument (position 0) is
9791 * the command itself, and the rest are user-provided args.
9792 */
9793RedisModuleString *RM_CommandFilterArgGet(RedisModuleCommandFilterCtx *fctx, int pos)
9794{
9795 if (pos < 0 || pos >= fctx->argc) return NULL;
9796 return fctx->argv[pos];
9797}
9798
9799/* Modify the filtered command by inserting a new argument at the specified
9800 * position. The specified RedisModuleString argument may be used by Redis
9801 * after the filter context is destroyed, so it must not be auto-memory
9802 * allocated, freed or used elsewhere.
9803 */
9804int RM_CommandFilterArgInsert(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg)
9805{
9806 int i;
9807
9808 if (pos < 0 || pos > fctx->argc) return REDISMODULE_ERR;
9809
9810 fctx->argv = zrealloc(fctx->argv, (fctx->argc+1)*sizeof(RedisModuleString *));
9811 for (i = fctx->argc; i > pos; i--) {
9812 fctx->argv[i] = fctx->argv[i-1];
9813 }
9814 fctx->argv[pos] = arg;
9815 fctx->argc++;
9816
9817 return REDISMODULE_OK;
9818}
9819
9820/* Modify the filtered command by replacing an existing argument with a new one.
9821 * The specified RedisModuleString argument may be used by Redis after the
9822 * filter context is destroyed, so it must not be auto-memory allocated, freed
9823 * or used elsewhere.
9824 */
9825int RM_CommandFilterArgReplace(RedisModuleCommandFilterCtx *fctx, int pos, RedisModuleString *arg)
9826{
9827 if (pos < 0 || pos >= fctx->argc) return REDISMODULE_ERR;
9828
9829 decrRefCount(fctx->argv[pos]);
9830 fctx->argv[pos] = arg;
9831
9832 return REDISMODULE_OK;
9833}
9834
9835/* Modify the filtered command by deleting an argument at the specified
9836 * position.
9837 */
9838int RM_CommandFilterArgDelete(RedisModuleCommandFilterCtx *fctx, int pos)
9839{
9840 int i;
9841 if (pos < 0 || pos >= fctx->argc) return REDISMODULE_ERR;
9842
9843 decrRefCount(fctx->argv[pos]);
9844 for (i = pos; i < fctx->argc-1; i++) {
9845 fctx->argv[i] = fctx->argv[i+1];
9846 }
9847 fctx->argc--;
9848
9849 return REDISMODULE_OK;
9850}
9851
9852/* For a given pointer allocated via RedisModule_Alloc() or
9853 * RedisModule_Realloc(), return the amount of memory allocated for it.
9854 * Note that this may be different (larger) than the memory we allocated
9855 * with the allocation calls, since sometimes the underlying allocator
9856 * will allocate more memory.
9857 */
9858size_t RM_MallocSize(void* ptr) {
9859 return zmalloc_size(ptr);
9860}
9861
9862/* Similar to RM_MallocSize, the difference is that RM_MallocUsableSize
9863 * returns the usable size of memory by the module. */
9864size_t RM_MallocUsableSize(void *ptr) {
9865 return zmalloc_usable_size(ptr);
9866}
9867
9868/* Same as RM_MallocSize, except it works on RedisModuleString pointers.
9869 */
9870size_t RM_MallocSizeString(RedisModuleString* str) {
9871 serverAssert(str->type == OBJ_STRING);
9872 return sizeof(*str) + getStringObjectSdsUsedMemory(str);
9873}
9874
9875/* Same as RM_MallocSize, except it works on RedisModuleDict pointers.
9876 * Note that the returned value is only the overhead of the underlying structures,
9877 * it does not include the allocation size of the keys and values.
9878 */
9879size_t RM_MallocSizeDict(RedisModuleDict* dict) {
9880 size_t size = sizeof(RedisModuleDict) + sizeof(rax);
9881 size += dict->rax->numnodes * sizeof(raxNode);
9882 /* For more info about this weird line, see streamRadixTreeMemoryUsage */
9883 size += dict->rax->numnodes * sizeof(long)*30;
9884 return size;
9885}
9886
9887/* Return the a number between 0 to 1 indicating the amount of memory
9888 * currently used, relative to the Redis "maxmemory" configuration.
9889 *
9890 * * 0 - No memory limit configured.
9891 * * Between 0 and 1 - The percentage of the memory used normalized in 0-1 range.
9892 * * Exactly 1 - Memory limit reached.
9893 * * Greater 1 - More memory used than the configured limit.
9894 */
9895float RM_GetUsedMemoryRatio(){
9896 float level;
9897 getMaxmemoryState(NULL, NULL, NULL, &level);
9898 return level;
9899}
9900
9901/* --------------------------------------------------------------------------
9902 * ## Scanning keyspace and hashes
9903 * -------------------------------------------------------------------------- */
9904
9905typedef void (*RedisModuleScanCB)(RedisModuleCtx *ctx, RedisModuleString *keyname, RedisModuleKey *key, void *privdata);
9906typedef struct {
9907 RedisModuleCtx *ctx;
9908 void* user_data;
9909 RedisModuleScanCB fn;
9910} ScanCBData;
9911
9912typedef struct RedisModuleScanCursor{
9913 unsigned long cursor;
9914 int done;
9915}RedisModuleScanCursor;
9916
9917static void moduleScanCallback(void *privdata, const dictEntry *de) {
9918 ScanCBData *data = privdata;
9919 sds key = dictGetKey(de);
9920 robj* val = dictGetVal(de);
9921 RedisModuleString *keyname = createObject(OBJ_STRING,sdsdup(key));
9922
9923 /* Setup the key handle. */
9924 RedisModuleKey kp = {0};
9925 moduleInitKey(&kp, data->ctx, keyname, val, REDISMODULE_READ);
9926
9927 data->fn(data->ctx, keyname, &kp, data->user_data);
9928
9929 moduleCloseKey(&kp);
9930 decrRefCount(keyname);
9931}
9932
9933/* Create a new cursor to be used with RedisModule_Scan */
9934RedisModuleScanCursor *RM_ScanCursorCreate() {
9935 RedisModuleScanCursor* cursor = zmalloc(sizeof(*cursor));
9936 cursor->cursor = 0;
9937 cursor->done = 0;
9938 return cursor;
9939}
9940
9941/* Restart an existing cursor. The keys will be rescanned. */
9942void RM_ScanCursorRestart(RedisModuleScanCursor *cursor) {
9943 cursor->cursor = 0;
9944 cursor->done = 0;
9945}
9946
9947/* Destroy the cursor struct. */
9948void RM_ScanCursorDestroy(RedisModuleScanCursor *cursor) {
9949 zfree(cursor);
9950}
9951
9952/* Scan API that allows a module to scan all the keys and value in
9953 * the selected db.
9954 *
9955 * Callback for scan implementation.
9956 *
9957 * void scan_callback(RedisModuleCtx *ctx, RedisModuleString *keyname,
9958 * RedisModuleKey *key, void *privdata);
9959 *
9960 * - `ctx`: the redis module context provided to for the scan.
9961 * - `keyname`: owned by the caller and need to be retained if used after this
9962 * function.
9963 * - `key`: holds info on the key and value, it is provided as best effort, in
9964 * some cases it might be NULL, in which case the user should (can) use
9965 * RedisModule_OpenKey() (and CloseKey too).
9966 * when it is provided, it is owned by the caller and will be free when the
9967 * callback returns.
9968 * - `privdata`: the user data provided to RedisModule_Scan().
9969 *
9970 * The way it should be used:
9971 *
9972 * RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
9973 * while(RedisModule_Scan(ctx, c, callback, privateData));
9974 * RedisModule_ScanCursorDestroy(c);
9975 *
9976 * It is also possible to use this API from another thread while the lock
9977 * is acquired during the actual call to RM_Scan:
9978 *
9979 * RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
9980 * RedisModule_ThreadSafeContextLock(ctx);
9981 * while(RedisModule_Scan(ctx, c, callback, privateData)){
9982 * RedisModule_ThreadSafeContextUnlock(ctx);
9983 * // do some background job
9984 * RedisModule_ThreadSafeContextLock(ctx);
9985 * }
9986 * RedisModule_ScanCursorDestroy(c);
9987 *
9988 * The function will return 1 if there are more elements to scan and
9989 * 0 otherwise, possibly setting errno if the call failed.
9990 *
9991 * It is also possible to restart an existing cursor using RM_ScanCursorRestart.
9992 *
9993 * IMPORTANT: This API is very similar to the Redis SCAN command from the
9994 * point of view of the guarantees it provides. This means that the API
9995 * may report duplicated keys, but guarantees to report at least one time
9996 * every key that was there from the start to the end of the scanning process.
9997 *
9998 * NOTE: If you do database changes within the callback, you should be aware
9999 * that the internal state of the database may change. For instance it is safe
10000 * to delete or modify the current key, but may not be safe to delete any
10001 * other key.
10002 * Moreover playing with the Redis keyspace while iterating may have the
10003 * effect of returning more duplicates. A safe pattern is to store the keys
10004 * names you want to modify elsewhere, and perform the actions on the keys
10005 * later when the iteration is complete. However this can cost a lot of
10006 * memory, so it may make sense to just operate on the current key when
10007 * possible during the iteration, given that this is safe. */
10008int RM_Scan(RedisModuleCtx *ctx, RedisModuleScanCursor *cursor, RedisModuleScanCB fn, void *privdata) {
10009 if (cursor->done) {
10010 errno = ENOENT;
10011 return 0;
10012 }
10013 int ret = 1;
10014 ScanCBData data = { ctx, privdata, fn };
10015 cursor->cursor = dictScan(ctx->client->db->dict, cursor->cursor, moduleScanCallback, NULL, &data);
10016 if (cursor->cursor == 0) {
10017 cursor->done = 1;
10018 ret = 0;
10019 }
10020 errno = 0;
10021 return ret;
10022}
10023
10024typedef void (*RedisModuleScanKeyCB)(RedisModuleKey *key, RedisModuleString *field, RedisModuleString *value, void *privdata);
10025typedef struct {
10026 RedisModuleKey *key;
10027 void* user_data;
10028 RedisModuleScanKeyCB fn;
10029} ScanKeyCBData;
10030
10031static void moduleScanKeyCallback(void *privdata, const dictEntry *de) {
10032 ScanKeyCBData *data = privdata;
10033 sds key = dictGetKey(de);
10034 robj *o = data->key->value;
10035 robj *field = createStringObject(key, sdslen(key));
10036 robj *value = NULL;
10037 if (o->type == OBJ_SET) {
10038 value = NULL;
10039 } else if (o->type == OBJ_HASH) {
10040 sds val = dictGetVal(de);
10041 value = createStringObject(val, sdslen(val));
10042 } else if (o->type == OBJ_ZSET) {
10043 double *val = (double*)dictGetVal(de);
10044 value = createStringObjectFromLongDouble(*val, 0);
10045 }
10046
10047 data->fn(data->key, field, value, data->user_data);
10048 decrRefCount(field);
10049 if (value) decrRefCount(value);
10050}
10051
10052/* Scan api that allows a module to scan the elements in a hash, set or sorted set key
10053 *
10054 * Callback for scan implementation.
10055 *
10056 * void scan_callback(RedisModuleKey *key, RedisModuleString* field, RedisModuleString* value, void *privdata);
10057 *
10058 * - key - the redis key context provided to for the scan.
10059 * - field - field name, owned by the caller and need to be retained if used
10060 * after this function.
10061 * - value - value string or NULL for set type, owned by the caller and need to
10062 * be retained if used after this function.
10063 * - privdata - the user data provided to RedisModule_ScanKey.
10064 *
10065 * The way it should be used:
10066 *
10067 * RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
10068 * RedisModuleKey *key = RedisModule_OpenKey(...)
10069 * while(RedisModule_ScanKey(key, c, callback, privateData));
10070 * RedisModule_CloseKey(key);
10071 * RedisModule_ScanCursorDestroy(c);
10072 *
10073 * It is also possible to use this API from another thread while the lock is acquired during
10074 * the actual call to RM_ScanKey, and re-opening the key each time:
10075 *
10076 * RedisModuleScanCursor *c = RedisModule_ScanCursorCreate();
10077 * RedisModule_ThreadSafeContextLock(ctx);
10078 * RedisModuleKey *key = RedisModule_OpenKey(...)
10079 * while(RedisModule_ScanKey(ctx, c, callback, privateData)){
10080 * RedisModule_CloseKey(key);
10081 * RedisModule_ThreadSafeContextUnlock(ctx);
10082 * // do some background job
10083 * RedisModule_ThreadSafeContextLock(ctx);
10084 * RedisModuleKey *key = RedisModule_OpenKey(...)
10085 * }
10086 * RedisModule_CloseKey(key);
10087 * RedisModule_ScanCursorDestroy(c);
10088 *
10089 * The function will return 1 if there are more elements to scan and 0 otherwise,
10090 * possibly setting errno if the call failed.
10091 * It is also possible to restart an existing cursor using RM_ScanCursorRestart.
10092 *
10093 * NOTE: Certain operations are unsafe while iterating the object. For instance
10094 * while the API guarantees to return at least one time all the elements that
10095 * are present in the data structure consistently from the start to the end
10096 * of the iteration (see HSCAN and similar commands documentation), the more
10097 * you play with the elements, the more duplicates you may get. In general
10098 * deleting the current element of the data structure is safe, while removing
10099 * the key you are iterating is not safe. */
10100int RM_ScanKey(RedisModuleKey *key, RedisModuleScanCursor *cursor, RedisModuleScanKeyCB fn, void *privdata) {
10101 if (key == NULL || key->value == NULL) {
10102 errno = EINVAL;
10103 return 0;
10104 }
10105 dict *ht = NULL;
10106 robj *o = key->value;
10107 if (o->type == OBJ_SET) {
10108 if (o->encoding == OBJ_ENCODING_HT)
10109 ht = o->ptr;
10110 } else if (o->type == OBJ_HASH) {
10111 if (o->encoding == OBJ_ENCODING_HT)
10112 ht = o->ptr;
10113 } else if (o->type == OBJ_ZSET) {
10114 if (o->encoding == OBJ_ENCODING_SKIPLIST)
10115 ht = ((zset *)o->ptr)->dict;
10116 } else {
10117 errno = EINVAL;
10118 return 0;
10119 }
10120 if (cursor->done) {
10121 errno = ENOENT;
10122 return 0;
10123 }
10124 int ret = 1;
10125 if (ht) {
10126 ScanKeyCBData data = { key, privdata, fn };
10127 cursor->cursor = dictScan(ht, cursor->cursor, moduleScanKeyCallback, NULL, &data);
10128 if (cursor->cursor == 0) {
10129 cursor->done = 1;
10130 ret = 0;
10131 }
10132 } else if (o->type == OBJ_SET && o->encoding == OBJ_ENCODING_INTSET) {
10133 int pos = 0;
10134 int64_t ll;
10135 while(intsetGet(o->ptr,pos++,&ll)) {
10136 robj *field = createObject(OBJ_STRING,sdsfromlonglong(ll));
10137 fn(key, field, NULL, privdata);
10138 decrRefCount(field);
10139 }
10140 cursor->cursor = 1;
10141 cursor->done = 1;
10142 ret = 0;
10143 } else if (o->type == OBJ_ZSET) {
10144 unsigned char *p = lpSeek(o->ptr,0);
10145 unsigned char *vstr;
10146 unsigned int vlen;
10147 long long vll;
10148 while(p) {
10149 vstr = lpGetValue(p,&vlen,&vll);
10150 robj *field = (vstr != NULL) ?
10151 createStringObject((char*)vstr,vlen) :
10152 createObject(OBJ_STRING,sdsfromlonglong(vll));
10153 p = lpNext(o->ptr,p);
10154 vstr = lpGetValue(p,&vlen,&vll);
10155 robj *value = (vstr != NULL) ?
10156 createStringObject((char*)vstr,vlen) :
10157 createObject(OBJ_STRING,sdsfromlonglong(vll));
10158 fn(key, field, value, privdata);
10159 p = lpNext(o->ptr,p);
10160 decrRefCount(field);
10161 decrRefCount(value);
10162 }
10163 cursor->cursor = 1;
10164 cursor->done = 1;
10165 ret = 0;
10166 } else if (o->type == OBJ_HASH) {
10167 unsigned char *p = lpFirst(o->ptr);
10168 unsigned char *vstr;
10169 int64_t vlen;
10170 unsigned char intbuf[LP_INTBUF_SIZE];
10171 while(p) {
10172 vstr = lpGet(p,&vlen,intbuf);
10173 robj *field = createStringObject((char*)vstr,vlen);
10174 p = lpNext(o->ptr,p);
10175 vstr = lpGet(p,&vlen,intbuf);
10176 robj *value = createStringObject((char*)vstr,vlen);
10177 fn(key, field, value, privdata);
10178 p = lpNext(o->ptr,p);
10179 decrRefCount(field);
10180 decrRefCount(value);
10181 }
10182 cursor->cursor = 1;
10183 cursor->done = 1;
10184 ret = 0;
10185 }
10186 errno = 0;
10187 return ret;
10188}
10189
10190
10191/* --------------------------------------------------------------------------
10192 * ## Module fork API
10193 * -------------------------------------------------------------------------- */
10194
10195/* Create a background child process with the current frozen snapshot of the
10196 * main process where you can do some processing in the background without
10197 * affecting / freezing the traffic and no need for threads and GIL locking.
10198 * Note that Redis allows for only one concurrent fork.
10199 * When the child wants to exit, it should call RedisModule_ExitFromChild.
10200 * If the parent wants to kill the child it should call RedisModule_KillForkChild
10201 * The done handler callback will be executed on the parent process when the
10202 * child existed (but not when killed)
10203 * Return: -1 on failure, on success the parent process will get a positive PID
10204 * of the child, and the child process will get 0.
10205 */
10206int RM_Fork(RedisModuleForkDoneHandler cb, void *user_data) {
10207 pid_t childpid;
10208
10209 if ((childpid = redisFork(CHILD_TYPE_MODULE)) == 0) {
10210 /* Child */
10211 redisSetProcTitle("redis-module-fork");
10212 } else if (childpid == -1) {
10213 serverLog(LL_WARNING,"Can't fork for module: %s", strerror(errno));
10214 } else {
10215 /* Parent */
10216 moduleForkInfo.done_handler = cb;
10217 moduleForkInfo.done_handler_user_data = user_data;
10218 serverLog(LL_VERBOSE, "Module fork started pid: %ld ", (long) childpid);
10219 }
10220 return childpid;
10221}
10222
10223/* The module is advised to call this function from the fork child once in a while,
10224 * so that it can report progress and COW memory to the parent which will be
10225 * reported in INFO.
10226 * The `progress` argument should between 0 and 1, or -1 when not available. */
10227void RM_SendChildHeartbeat(double progress) {
10228 sendChildInfoGeneric(CHILD_INFO_TYPE_CURRENT_INFO, 0, progress, "Module fork");
10229}
10230
10231/* Call from the child process when you want to terminate it.
10232 * retcode will be provided to the done handler executed on the parent process.
10233 */
10234int RM_ExitFromChild(int retcode) {
10235 sendChildCowInfo(CHILD_INFO_TYPE_MODULE_COW_SIZE, "Module fork");
10236 exitFromChild(retcode);
10237 return REDISMODULE_OK;
10238}
10239
10240/* Kill the active module forked child, if there is one active and the
10241 * pid matches, and returns C_OK. Otherwise if there is no active module
10242 * child or the pid does not match, return C_ERR without doing anything. */
10243int TerminateModuleForkChild(int child_pid, int wait) {
10244 /* Module child should be active and pid should match. */
10245 if (server.child_type != CHILD_TYPE_MODULE ||
10246 server.child_pid != child_pid) return C_ERR;
10247
10248 int statloc;
10249 serverLog(LL_VERBOSE,"Killing running module fork child: %ld",
10250 (long) server.child_pid);
10251 if (kill(server.child_pid,SIGUSR1) != -1 && wait) {
10252 while(waitpid(server.child_pid, &statloc, 0) !=
10253 server.child_pid);
10254 }
10255 /* Reset the buffer accumulating changes while the child saves. */
10256 resetChildState();
10257 moduleForkInfo.done_handler = NULL;
10258 moduleForkInfo.done_handler_user_data = NULL;
10259 return C_OK;
10260}
10261
10262/* Can be used to kill the forked child process from the parent process.
10263 * child_pid would be the return value of RedisModule_Fork. */
10264int RM_KillForkChild(int child_pid) {
10265 /* Kill module child, wait for child exit. */
10266 if (TerminateModuleForkChild(child_pid,1) == C_OK)
10267 return REDISMODULE_OK;
10268 else
10269 return REDISMODULE_ERR;
10270}
10271
10272void ModuleForkDoneHandler(int exitcode, int bysignal) {
10273 serverLog(LL_NOTICE,
10274 "Module fork exited pid: %ld, retcode: %d, bysignal: %d",
10275 (long) server.child_pid, exitcode, bysignal);
10276 if (moduleForkInfo.done_handler) {
10277 moduleForkInfo.done_handler(exitcode, bysignal,
10278 moduleForkInfo.done_handler_user_data);
10279 }
10280
10281 moduleForkInfo.done_handler = NULL;
10282 moduleForkInfo.done_handler_user_data = NULL;
10283}
10284
10285/* --------------------------------------------------------------------------
10286 * ## Server hooks implementation
10287 * -------------------------------------------------------------------------- */
10288
10289/* This must be synced with REDISMODULE_EVENT_*
10290 * We use -1 (MAX_UINT64) to denote that this event doesn't have
10291 * a data structure associated with it. We use MAX_UINT64 on purpose,
10292 * in order to pass the check in RedisModule_SubscribeToServerEvent. */
10293static uint64_t moduleEventVersions[] = {
10294 REDISMODULE_REPLICATIONINFO_VERSION, /* REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED */
10295 -1, /* REDISMODULE_EVENT_PERSISTENCE */
10296 REDISMODULE_FLUSHINFO_VERSION, /* REDISMODULE_EVENT_FLUSHDB */
10297 -1, /* REDISMODULE_EVENT_LOADING */
10298 REDISMODULE_CLIENTINFO_VERSION, /* REDISMODULE_EVENT_CLIENT_CHANGE */
10299 -1, /* REDISMODULE_EVENT_SHUTDOWN */
10300 -1, /* REDISMODULE_EVENT_REPLICA_CHANGE */
10301 -1, /* REDISMODULE_EVENT_MASTER_LINK_CHANGE */
10302 REDISMODULE_CRON_LOOP_VERSION, /* REDISMODULE_EVENT_CRON_LOOP */
10303 REDISMODULE_MODULE_CHANGE_VERSION, /* REDISMODULE_EVENT_MODULE_CHANGE */
10304 REDISMODULE_LOADING_PROGRESS_VERSION, /* REDISMODULE_EVENT_LOADING_PROGRESS */
10305 REDISMODULE_SWAPDBINFO_VERSION, /* REDISMODULE_EVENT_SWAPDB */
10306 -1, /* REDISMODULE_EVENT_REPL_BACKUP */
10307 -1, /* REDISMODULE_EVENT_FORK_CHILD */
10308 -1, /* REDISMODULE_EVENT_REPL_ASYNC_LOAD */
10309 -1, /* REDISMODULE_EVENT_EVENTLOOP */
10310 -1, /* REDISMODULE_EVENT_CONFIG */
10311};
10312
10313/* Register to be notified, via a callback, when the specified server event
10314 * happens. The callback is called with the event as argument, and an additional
10315 * argument which is a void pointer and should be cased to a specific type
10316 * that is event-specific (but many events will just use NULL since they do not
10317 * have additional information to pass to the callback).
10318 *
10319 * If the callback is NULL and there was a previous subscription, the module
10320 * will be unsubscribed. If there was a previous subscription and the callback
10321 * is not null, the old callback will be replaced with the new one.
10322 *
10323 * The callback must be of this type:
10324 *
10325 * int (*RedisModuleEventCallback)(RedisModuleCtx *ctx,
10326 * RedisModuleEvent eid,
10327 * uint64_t subevent,
10328 * void *data);
10329 *
10330 * The 'ctx' is a normal Redis module context that the callback can use in
10331 * order to call other modules APIs. The 'eid' is the event itself, this
10332 * is only useful in the case the module subscribed to multiple events: using
10333 * the 'id' field of this structure it is possible to check if the event
10334 * is one of the events we registered with this callback. The 'subevent' field
10335 * depends on the event that fired.
10336 *
10337 * Finally the 'data' pointer may be populated, only for certain events, with
10338 * more relevant data.
10339 *
10340 * Here is a list of events you can use as 'eid' and related sub events:
10341 *
10342 * * RedisModuleEvent_ReplicationRoleChanged:
10343 *
10344 * This event is called when the instance switches from master
10345 * to replica or the other way around, however the event is
10346 * also called when the replica remains a replica but starts to
10347 * replicate with a different master.
10348 *
10349 * The following sub events are available:
10350 *
10351 * * `REDISMODULE_SUBEVENT_REPLROLECHANGED_NOW_MASTER`
10352 * * `REDISMODULE_SUBEVENT_REPLROLECHANGED_NOW_REPLICA`
10353 *
10354 * The 'data' field can be casted by the callback to a
10355 * `RedisModuleReplicationInfo` structure with the following fields:
10356 *
10357 * int master; // true if master, false if replica
10358 * char *masterhost; // master instance hostname for NOW_REPLICA
10359 * int masterport; // master instance port for NOW_REPLICA
10360 * char *replid1; // Main replication ID
10361 * char *replid2; // Secondary replication ID
10362 * uint64_t repl1_offset; // Main replication offset
10363 * uint64_t repl2_offset; // Offset of replid2 validity
10364 *
10365 * * RedisModuleEvent_Persistence
10366 *
10367 * This event is called when RDB saving or AOF rewriting starts
10368 * and ends. The following sub events are available:
10369 *
10370 * * `REDISMODULE_SUBEVENT_PERSISTENCE_RDB_START`
10371 * * `REDISMODULE_SUBEVENT_PERSISTENCE_AOF_START`
10372 * * `REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_RDB_START`
10373 * * `REDISMODULE_SUBEVENT_PERSISTENCE_SYNC_AOF_START`
10374 * * `REDISMODULE_SUBEVENT_PERSISTENCE_ENDED`
10375 * * `REDISMODULE_SUBEVENT_PERSISTENCE_FAILED`
10376 *
10377 * The above events are triggered not just when the user calls the
10378 * relevant commands like BGSAVE, but also when a saving operation
10379 * or AOF rewriting occurs because of internal server triggers.
10380 * The SYNC_RDB_START sub events are happening in the foreground due to
10381 * SAVE command, FLUSHALL, or server shutdown, and the other RDB and
10382 * AOF sub events are executed in a background fork child, so any
10383 * action the module takes can only affect the generated AOF or RDB,
10384 * but will not be reflected in the parent process and affect connected
10385 * clients and commands. Also note that the AOF_START sub event may end
10386 * up saving RDB content in case of an AOF with rdb-preamble.
10387 *
10388 * * RedisModuleEvent_FlushDB
10389 *
10390 * The FLUSHALL, FLUSHDB or an internal flush (for instance
10391 * because of replication, after the replica synchronization)
10392 * happened. The following sub events are available:
10393 *
10394 * * `REDISMODULE_SUBEVENT_FLUSHDB_START`
10395 * * `REDISMODULE_SUBEVENT_FLUSHDB_END`
10396 *
10397 * The data pointer can be casted to a RedisModuleFlushInfo
10398 * structure with the following fields:
10399 *
10400 * int32_t async; // True if the flush is done in a thread.
10401 * // See for instance FLUSHALL ASYNC.
10402 * // In this case the END callback is invoked
10403 * // immediately after the database is put
10404 * // in the free list of the thread.
10405 * int32_t dbnum; // Flushed database number, -1 for all the DBs
10406 * // in the case of the FLUSHALL operation.
10407 *
10408 * The start event is called *before* the operation is initiated, thus
10409 * allowing the callback to call DBSIZE or other operation on the
10410 * yet-to-free keyspace.
10411 *
10412 * * RedisModuleEvent_Loading
10413 *
10414 * Called on loading operations: at startup when the server is
10415 * started, but also after a first synchronization when the
10416 * replica is loading the RDB file from the master.
10417 * The following sub events are available:
10418 *
10419 * * `REDISMODULE_SUBEVENT_LOADING_RDB_START`
10420 * * `REDISMODULE_SUBEVENT_LOADING_AOF_START`
10421 * * `REDISMODULE_SUBEVENT_LOADING_REPL_START`
10422 * * `REDISMODULE_SUBEVENT_LOADING_ENDED`
10423 * * `REDISMODULE_SUBEVENT_LOADING_FAILED`
10424 *
10425 * Note that AOF loading may start with an RDB data in case of
10426 * rdb-preamble, in which case you'll only receive an AOF_START event.
10427 *
10428 * * RedisModuleEvent_ClientChange
10429 *
10430 * Called when a client connects or disconnects.
10431 * The data pointer can be casted to a RedisModuleClientInfo
10432 * structure, documented in RedisModule_GetClientInfoById().
10433 * The following sub events are available:
10434 *
10435 * * `REDISMODULE_SUBEVENT_CLIENT_CHANGE_CONNECTED`
10436 * * `REDISMODULE_SUBEVENT_CLIENT_CHANGE_DISCONNECTED`
10437 *
10438 * * RedisModuleEvent_Shutdown
10439 *
10440 * The server is shutting down. No subevents are available.
10441 *
10442 * * RedisModuleEvent_ReplicaChange
10443 *
10444 * This event is called when the instance (that can be both a
10445 * master or a replica) get a new online replica, or lose a
10446 * replica since it gets disconnected.
10447 * The following sub events are available:
10448 *
10449 * * `REDISMODULE_SUBEVENT_REPLICA_CHANGE_ONLINE`
10450 * * `REDISMODULE_SUBEVENT_REPLICA_CHANGE_OFFLINE`
10451 *
10452 * No additional information is available so far: future versions
10453 * of Redis will have an API in order to enumerate the replicas
10454 * connected and their state.
10455 *
10456 * * RedisModuleEvent_CronLoop
10457 *
10458 * This event is called every time Redis calls the serverCron()
10459 * function in order to do certain bookkeeping. Modules that are
10460 * required to do operations from time to time may use this callback.
10461 * Normally Redis calls this function 10 times per second, but
10462 * this changes depending on the "hz" configuration.
10463 * No sub events are available.
10464 *
10465 * The data pointer can be casted to a RedisModuleCronLoop
10466 * structure with the following fields:
10467 *
10468 * int32_t hz; // Approximate number of events per second.
10469 *
10470 * * RedisModuleEvent_MasterLinkChange
10471 *
10472 * This is called for replicas in order to notify when the
10473 * replication link becomes functional (up) with our master,
10474 * or when it goes down. Note that the link is not considered
10475 * up when we just connected to the master, but only if the
10476 * replication is happening correctly.
10477 * The following sub events are available:
10478 *
10479 * * `REDISMODULE_SUBEVENT_MASTER_LINK_UP`
10480 * * `REDISMODULE_SUBEVENT_MASTER_LINK_DOWN`
10481 *
10482 * * RedisModuleEvent_ModuleChange
10483 *
10484 * This event is called when a new module is loaded or one is unloaded.
10485 * The following sub events are available:
10486 *
10487 * * `REDISMODULE_SUBEVENT_MODULE_LOADED`
10488 * * `REDISMODULE_SUBEVENT_MODULE_UNLOADED`
10489 *
10490 * The data pointer can be casted to a RedisModuleModuleChange
10491 * structure with the following fields:
10492 *
10493 * const char* module_name; // Name of module loaded or unloaded.
10494 * int32_t module_version; // Module version.
10495 *
10496 * * RedisModuleEvent_LoadingProgress
10497 *
10498 * This event is called repeatedly called while an RDB or AOF file
10499 * is being loaded.
10500 * The following sub events are available:
10501 *
10502 * * `REDISMODULE_SUBEVENT_LOADING_PROGRESS_RDB`
10503 * * `REDISMODULE_SUBEVENT_LOADING_PROGRESS_AOF`
10504 *
10505 * The data pointer can be casted to a RedisModuleLoadingProgress
10506 * structure with the following fields:
10507 *
10508 * int32_t hz; // Approximate number of events per second.
10509 * int32_t progress; // Approximate progress between 0 and 1024,
10510 * // or -1 if unknown.
10511 *
10512 * * RedisModuleEvent_SwapDB
10513 *
10514 * This event is called when a SWAPDB command has been successfully
10515 * Executed.
10516 * For this event call currently there is no subevents available.
10517 *
10518 * The data pointer can be casted to a RedisModuleSwapDbInfo
10519 * structure with the following fields:
10520 *
10521 * int32_t dbnum_first; // Swap Db first dbnum
10522 * int32_t dbnum_second; // Swap Db second dbnum
10523 *
10524 * * RedisModuleEvent_ReplBackup
10525 *
10526 * WARNING: Replication Backup events are deprecated since Redis 7.0 and are never fired.
10527 * See RedisModuleEvent_ReplAsyncLoad for understanding how Async Replication Loading events
10528 * are now triggered when repl-diskless-load is set to swapdb.
10529 *
10530 * Called when repl-diskless-load config is set to swapdb,
10531 * And redis needs to backup the current database for the
10532 * possibility to be restored later. A module with global data and
10533 * maybe with aux_load and aux_save callbacks may need to use this
10534 * notification to backup / restore / discard its globals.
10535 * The following sub events are available:
10536 *
10537 * * `REDISMODULE_SUBEVENT_REPL_BACKUP_CREATE`
10538 * * `REDISMODULE_SUBEVENT_REPL_BACKUP_RESTORE`
10539 * * `REDISMODULE_SUBEVENT_REPL_BACKUP_DISCARD`
10540 *
10541 * * RedisModuleEvent_ReplAsyncLoad
10542 *
10543 * Called when repl-diskless-load config is set to swapdb and a replication with a master of same
10544 * data set history (matching replication ID) occurs.
10545 * In which case redis serves current data set while loading new database in memory from socket.
10546 * Modules must have declared they support this mechanism in order to activate it, through
10547 * REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD flag.
10548 * The following sub events are available:
10549 *
10550 * * `REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_STARTED`
10551 * * `REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_ABORTED`
10552 * * `REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_COMPLETED`
10553 *
10554 * * RedisModuleEvent_ForkChild
10555 *
10556 * Called when a fork child (AOFRW, RDBSAVE, module fork...) is born/dies
10557 * The following sub events are available:
10558 *
10559 * * `REDISMODULE_SUBEVENT_FORK_CHILD_BORN`
10560 * * `REDISMODULE_SUBEVENT_FORK_CHILD_DIED`
10561 *
10562 * * RedisModuleEvent_EventLoop
10563 *
10564 * Called on each event loop iteration, once just before the event loop goes
10565 * to sleep or just after it wakes up.
10566 * The following sub events are available:
10567 *
10568 * * `REDISMODULE_SUBEVENT_EVENTLOOP_BEFORE_SLEEP`
10569 * * `REDISMODULE_SUBEVENT_EVENTLOOP_AFTER_SLEEP`
10570 *
10571 * * RedisModule_Event_Config
10572 *
10573 * Called when a configuration event happens
10574 * The following sub events are available:
10575 *
10576 * * `REDISMODULE_SUBEVENT_CONFIG_CHANGE`
10577 *
10578 * The data pointer can be casted to a RedisModuleConfigChange
10579 * structure with the following fields:
10580 *
10581 * const char **config_names; // An array of C string pointers containing the
10582 * // name of each modified configuration item
10583 * uint32_t num_changes; // The number of elements in the config_names array
10584 *
10585 * The function returns REDISMODULE_OK if the module was successfully subscribed
10586 * for the specified event. If the API is called from a wrong context or unsupported event
10587 * is given then REDISMODULE_ERR is returned. */
10588int RM_SubscribeToServerEvent(RedisModuleCtx *ctx, RedisModuleEvent event, RedisModuleEventCallback callback) {
10589 RedisModuleEventListener *el;
10590
10591 /* Protect in case of calls from contexts without a module reference. */
10592 if (ctx->module == NULL) return REDISMODULE_ERR;
10593 if (event.id >= _REDISMODULE_EVENT_NEXT) return REDISMODULE_ERR;
10594 if (event.dataver > moduleEventVersions[event.id]) return REDISMODULE_ERR; /* Module compiled with a newer redismodule.h than we support */
10595
10596 /* Search an event matching this module and event ID. */
10597 listIter li;
10598 listNode *ln;
10599 listRewind(RedisModule_EventListeners,&li);
10600 while((ln = listNext(&li))) {
10601 el = ln->value;
10602 if (el->module == ctx->module && el->event.id == event.id)
10603 break; /* Matching event found. */
10604 }
10605
10606 /* Modify or remove the event listener if we already had one. */
10607 if (ln) {
10608 if (callback == NULL) {
10609 listDelNode(RedisModule_EventListeners,ln);
10610 zfree(el);
10611 } else {
10612 el->callback = callback; /* Update the callback with the new one. */
10613 }
10614 return REDISMODULE_OK;
10615 }
10616
10617 /* No event found, we need to add a new one. */
10618 el = zmalloc(sizeof(*el));
10619 el->module = ctx->module;
10620 el->event = event;
10621 el->callback = callback;
10622 listAddNodeTail(RedisModule_EventListeners,el);
10623 return REDISMODULE_OK;
10624}
10625
10626/**
10627 * For a given server event and subevent, return zero if the
10628 * subevent is not supported and non-zero otherwise.
10629 */
10630int RM_IsSubEventSupported(RedisModuleEvent event, int64_t subevent) {
10631 switch (event.id) {
10632 case REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED:
10633 return subevent < _REDISMODULE_EVENT_REPLROLECHANGED_NEXT;
10634 case REDISMODULE_EVENT_PERSISTENCE:
10635 return subevent < _REDISMODULE_SUBEVENT_PERSISTENCE_NEXT;
10636 case REDISMODULE_EVENT_FLUSHDB:
10637 return subevent < _REDISMODULE_SUBEVENT_FLUSHDB_NEXT;
10638 case REDISMODULE_EVENT_LOADING:
10639 return subevent < _REDISMODULE_SUBEVENT_LOADING_NEXT;
10640 case REDISMODULE_EVENT_CLIENT_CHANGE:
10641 return subevent < _REDISMODULE_SUBEVENT_CLIENT_CHANGE_NEXT;
10642 case REDISMODULE_EVENT_SHUTDOWN:
10643 return subevent < _REDISMODULE_SUBEVENT_SHUTDOWN_NEXT;
10644 case REDISMODULE_EVENT_REPLICA_CHANGE:
10645 return subevent < _REDISMODULE_EVENT_REPLROLECHANGED_NEXT;
10646 case REDISMODULE_EVENT_MASTER_LINK_CHANGE:
10647 return subevent < _REDISMODULE_SUBEVENT_MASTER_NEXT;
10648 case REDISMODULE_EVENT_CRON_LOOP:
10649 return subevent < _REDISMODULE_SUBEVENT_CRON_LOOP_NEXT;
10650 case REDISMODULE_EVENT_MODULE_CHANGE:
10651 return subevent < _REDISMODULE_SUBEVENT_MODULE_NEXT;
10652 case REDISMODULE_EVENT_LOADING_PROGRESS:
10653 return subevent < _REDISMODULE_SUBEVENT_LOADING_PROGRESS_NEXT;
10654 case REDISMODULE_EVENT_SWAPDB:
10655 return subevent < _REDISMODULE_SUBEVENT_SWAPDB_NEXT;
10656 case REDISMODULE_EVENT_REPL_ASYNC_LOAD:
10657 return subevent < _REDISMODULE_SUBEVENT_REPL_ASYNC_LOAD_NEXT;
10658 case REDISMODULE_EVENT_FORK_CHILD:
10659 return subevent < _REDISMODULE_SUBEVENT_FORK_CHILD_NEXT;
10660 case REDISMODULE_EVENT_EVENTLOOP:
10661 return subevent < _REDISMODULE_SUBEVENT_EVENTLOOP_NEXT;
10662 case REDISMODULE_EVENT_CONFIG:
10663 return subevent < _REDISMODULE_SUBEVENT_CONFIG_NEXT;
10664 default:
10665 break;
10666 }
10667 return 0;
10668}
10669
10670/* This is called by the Redis internals every time we want to fire an
10671 * event that can be intercepted by some module. The pointer 'data' is useful
10672 * in order to populate the event-specific structure when needed, in order
10673 * to return the structure with more information to the callback.
10674 *
10675 * 'eid' and 'subid' are just the main event ID and the sub event associated
10676 * with the event, depending on what exactly happened. */
10677void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
10678 /* Fast path to return ASAP if there is nothing to do, avoiding to
10679 * setup the iterator and so forth: we want this call to be extremely
10680 * cheap if there are no registered modules. */
10681 if (listLength(RedisModule_EventListeners) == 0) return;
10682
10683 listIter li;
10684 listNode *ln;
10685 listRewind(RedisModule_EventListeners,&li);
10686 while((ln = listNext(&li))) {
10687 RedisModuleEventListener *el = ln->value;
10688 if (el->event.id == eid) {
10689 RedisModuleCtx ctx;
10690 if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) {
10691 /* In the case of client changes, we're pushing the real client
10692 * so the event handler can mutate it if needed. For example,
10693 * to change its authentication state in a way that does not
10694 * depend on specific commands executed later.
10695 */
10696 moduleCreateContext(&ctx,el->module,REDISMODULE_CTX_NONE);
10697 ctx.client = (client *) data;
10698 } else {
10699 moduleCreateContext(&ctx,el->module,REDISMODULE_CTX_TEMP_CLIENT);
10700 }
10701
10702 void *moduledata = NULL;
10703 RedisModuleClientInfoV1 civ1;
10704 RedisModuleReplicationInfoV1 riv1;
10705 RedisModuleModuleChangeV1 mcv1;
10706 /* Start at DB zero by default when calling the handler. It's
10707 * up to the specific event setup to change it when it makes
10708 * sense. For instance for FLUSHDB events we select the correct
10709 * DB automatically. */
10710 selectDb(ctx.client, 0);
10711
10712 /* Event specific context and data pointer setup. */
10713 if (eid == REDISMODULE_EVENT_CLIENT_CHANGE) {
10714 serverAssert(modulePopulateClientInfoStructure(&civ1,data, el->event.dataver) == REDISMODULE_OK);
10715 moduledata = &civ1;
10716 } else if (eid == REDISMODULE_EVENT_REPLICATION_ROLE_CHANGED) {
10717 serverAssert(modulePopulateReplicationInfoStructure(&riv1,el->event.dataver) == REDISMODULE_OK);
10718 moduledata = &riv1;
10719 } else if (eid == REDISMODULE_EVENT_FLUSHDB) {
10720 moduledata = data;
10721 RedisModuleFlushInfoV1 *fi = data;
10722 if (fi->dbnum != -1)
10723 selectDb(ctx.client, fi->dbnum);
10724 } else if (eid == REDISMODULE_EVENT_MODULE_CHANGE) {
10725 RedisModule *m = data;
10726 if (m == el->module) {
10727 moduleFreeContext(&ctx);
10728 continue;
10729 }
10730 mcv1.version = REDISMODULE_MODULE_CHANGE_VERSION;
10731 mcv1.module_name = m->name;
10732 mcv1.module_version = m->ver;
10733 moduledata = &mcv1;
10734 } else if (eid == REDISMODULE_EVENT_LOADING_PROGRESS) {
10735 moduledata = data;
10736 } else if (eid == REDISMODULE_EVENT_CRON_LOOP) {
10737 moduledata = data;
10738 } else if (eid == REDISMODULE_EVENT_SWAPDB) {
10739 moduledata = data;
10740 } else if (eid == REDISMODULE_EVENT_CONFIG) {
10741 moduledata = data;
10742 }
10743
10744 el->module->in_hook++;
10745 el->callback(&ctx,el->event,subid,moduledata);
10746 el->module->in_hook--;
10747
10748 moduleFreeContext(&ctx);
10749 }
10750 }
10751}
10752
10753/* Remove all the listeners for this module: this is used before unloading
10754 * a module. */
10755void moduleUnsubscribeAllServerEvents(RedisModule *module) {
10756 RedisModuleEventListener *el;
10757 listIter li;
10758 listNode *ln;
10759 listRewind(RedisModule_EventListeners,&li);
10760
10761 while((ln = listNext(&li))) {
10762 el = ln->value;
10763 if (el->module == module) {
10764 listDelNode(RedisModule_EventListeners,ln);
10765 zfree(el);
10766 }
10767 }
10768}
10769
10770void processModuleLoadingProgressEvent(int is_aof) {
10771 long long now = server.ustime;
10772 static long long next_event = 0;
10773 if (now >= next_event) {
10774 /* Fire the loading progress modules end event. */
10775 int progress = -1;
10776 if (server.loading_total_bytes)
10777 progress = (server.loading_loaded_bytes<<10) / server.loading_total_bytes;
10778 RedisModuleLoadingProgressV1 fi = {REDISMODULE_LOADING_PROGRESS_VERSION,
10779 server.hz,
10780 progress};
10781 moduleFireServerEvent(REDISMODULE_EVENT_LOADING_PROGRESS,
10782 is_aof?
10783 REDISMODULE_SUBEVENT_LOADING_PROGRESS_AOF:
10784 REDISMODULE_SUBEVENT_LOADING_PROGRESS_RDB,
10785 &fi);
10786 /* decide when the next event should fire. */
10787 next_event = now + 1000000 / server.hz;
10788 }
10789}
10790
10791/* When a module key is deleted (in dbAsyncDelete/dbSyncDelete/dbOverwrite), it
10792* will be called to tell the module which key is about to be released. */
10793void moduleNotifyKeyUnlink(robj *key, robj *val, int dbid) {
10794 if (val->type == OBJ_MODULE) {
10795 moduleValue *mv = val->ptr;
10796 moduleType *mt = mv->type;
10797 /* We prefer to use the enhanced version. */
10798 if (mt->unlink2 != NULL) {
10799 RedisModuleKeyOptCtx ctx = {key, NULL, dbid, -1};
10800 mt->unlink2(&ctx,mv->value);
10801 } else if (mt->unlink != NULL) {
10802 mt->unlink(key,mv->value);
10803 }
10804 }
10805}
10806
10807/* Return the free_effort of the module, it will automatically choose to call
10808 * `free_effort` or `free_effort2`, and the default return value is 1.
10809 * value of 0 means very high effort (always asynchronous freeing). */
10810size_t moduleGetFreeEffort(robj *key, robj *val, int dbid) {
10811 moduleValue *mv = val->ptr;
10812 moduleType *mt = mv->type;
10813 size_t effort = 1;
10814 /* We prefer to use the enhanced version. */
10815 if (mt->free_effort2 != NULL) {
10816 RedisModuleKeyOptCtx ctx = {key, NULL, dbid, -1};
10817 effort = mt->free_effort2(&ctx,mv->value);
10818 } else if (mt->free_effort != NULL) {
10819 effort = mt->free_effort(key,mv->value);
10820 }
10821
10822 return effort;
10823}
10824
10825/* Return the memory usage of the module, it will automatically choose to call
10826 * `mem_usage` or `mem_usage2`, and the default return value is 0. */
10827size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid) {
10828 moduleValue *mv = val->ptr;
10829 moduleType *mt = mv->type;
10830 size_t size = 0;
10831 /* We prefer to use the enhanced version. */
10832 if (mt->mem_usage2 != NULL) {
10833 RedisModuleKeyOptCtx ctx = {key, NULL, dbid, -1};
10834 size = mt->mem_usage2(&ctx, mv->value, sample_size);
10835 } else if (mt->mem_usage != NULL) {
10836 size = mt->mem_usage(mv->value);
10837 }
10838
10839 return size;
10840}
10841
10842/* --------------------------------------------------------------------------
10843 * Modules API internals
10844 * -------------------------------------------------------------------------- */
10845
10846/* server.moduleapi dictionary type. Only uses plain C strings since
10847 * this gets queries from modules. */
10848
10849uint64_t dictCStringKeyHash(const void *key) {
10850 return dictGenHashFunction((unsigned char*)key, strlen((char*)key));
10851}
10852
10853int dictCStringKeyCompare(dict *d, const void *key1, const void *key2) {
10854 UNUSED(d);
10855 return strcmp(key1,key2) == 0;
10856}
10857
10858dictType moduleAPIDictType = {
10859 dictCStringKeyHash, /* hash function */
10860 NULL, /* key dup */
10861 NULL, /* val dup */
10862 dictCStringKeyCompare, /* key compare */
10863 NULL, /* key destructor */
10864 NULL, /* val destructor */
10865 NULL /* allow to expand */
10866};
10867
10868int moduleRegisterApi(const char *funcname, void *funcptr) {
10869 return dictAdd(server.moduleapi, (char*)funcname, funcptr);
10870}
10871
10872#define REGISTER_API(name) \
10873 moduleRegisterApi("RedisModule_" #name, (void *)(unsigned long)RM_ ## name)
10874
10875/* Global initialization at Redis startup. */
10876void moduleRegisterCoreAPI(void);
10877
10878/* Currently, this function is just a placeholder for the module system
10879 * initialization steps that need to be run after server initialization.
10880 * A previous issue, selectDb() in createClient() requires that server.db has
10881 * been initialized, see #7323. */
10882void moduleInitModulesSystemLast(void) {
10883}
10884
10885
10886dictType sdsKeyValueHashDictType = {
10887 dictSdsCaseHash, /* hash function */
10888 NULL, /* key dup */
10889 NULL, /* val dup */
10890 dictSdsKeyCaseCompare, /* key compare */
10891 dictSdsDestructor, /* key destructor */
10892 dictSdsDestructor, /* val destructor */
10893 NULL /* allow to expand */
10894};
10895
10896void moduleInitModulesSystem(void) {
10897 moduleUnblockedClients = listCreate();
10898 server.loadmodule_queue = listCreate();
10899 server.module_configs_queue = dictCreate(&sdsKeyValueHashDictType);
10900 modules = dictCreate(&modulesDictType);
10901
10902 /* Set up the keyspace notification subscriber list and static client */
10903 moduleKeyspaceSubscribers = listCreate();
10904
10905 /* Set up filter list */
10906 moduleCommandFilters = listCreate();
10907
10908 moduleRegisterCoreAPI();
10909
10910 /* Create a pipe for module threads to be able to wake up the redis main thread.
10911 * Make the pipe non blocking. This is just a best effort aware mechanism
10912 * and we do not want to block not in the read nor in the write half.
10913 * Enable close-on-exec flag on pipes in case of the fork-exec system calls in
10914 * sentinels or redis servers. */
10915 if (anetPipe(server.module_pipe, O_CLOEXEC|O_NONBLOCK, O_CLOEXEC|O_NONBLOCK) == -1) {
10916 serverLog(LL_WARNING,
10917 "Can't create the pipe for module threads: %s", strerror(errno));
10918 exit(1);
10919 }
10920
10921 /* Create the timers radix tree. */
10922 Timers = raxNew();
10923
10924 /* Setup the event listeners data structures. */
10925 RedisModule_EventListeners = listCreate();
10926
10927 /* Making sure moduleEventVersions is synced with the number of events. */
10928 serverAssert(sizeof(moduleEventVersions)/sizeof(moduleEventVersions[0]) == _REDISMODULE_EVENT_NEXT);
10929
10930 /* Our thread-safe contexts GIL must start with already locked:
10931 * it is just unlocked when it's safe. */
10932 pthread_mutex_lock(&moduleGIL);
10933}
10934
10935void modulesCron(void) {
10936 /* Check number of temporary clients in the pool and free the unused ones
10937 * since the last cron. moduleTempClientMinCount tracks minimum count of
10938 * clients in the pool since the last cron. This is the number of clients
10939 * that we didn't use for the last cron period. */
10940
10941 /* Limit the max client count to be freed at once to avoid latency spikes.*/
10942 int iteration = 50;
10943 /* We are freeing clients if we have more than 8 unused clients. Keeping
10944 * small amount of clients to avoid client allocation costs if temporary
10945 * clients are required after some idle period. */
10946 const unsigned int min_client = 8;
10947 while (iteration > 0 && moduleTempClientCount > 0 && moduleTempClientMinCount > min_client) {
10948 client *c = moduleTempClients[--moduleTempClientCount];
10949 freeClient(c);
10950 iteration--;
10951 moduleTempClientMinCount--;
10952 }
10953 moduleTempClientMinCount = moduleTempClientCount;
10954
10955 /* Shrink moduleTempClients array itself if it is wasting some space */
10956 if (moduleTempClientCap > 32 && moduleTempClientCap > moduleTempClientCount * 4) {
10957 moduleTempClientCap /= 4;
10958 moduleTempClients = zrealloc(moduleTempClients,sizeof(client*)*moduleTempClientCap);
10959 }
10960}
10961
10962void moduleLoadQueueEntryFree(struct moduleLoadQueueEntry *loadmod) {
10963 if (!loadmod) return;
10964 sdsfree(loadmod->path);
10965 for (int i = 0; i < loadmod->argc; i++) {
10966 decrRefCount(loadmod->argv[i]);
10967 }
10968 zfree(loadmod->argv);
10969 zfree(loadmod);
10970}
10971
10972/* Remove Module Configs from standardConfig array in config.c */
10973void moduleRemoveConfigs(RedisModule *module) {
10974 listIter li;
10975 listNode *ln;
10976 listRewind(module->module_configs, &li);
10977 while ((ln = listNext(&li))) {
10978 ModuleConfig *config = listNodeValue(ln);
10979 sds module_name = sdsnew(module->name);
10980 sds full_name = sdscat(sdscat(module_name, "."), config->name); /* ModuleName.ModuleConfig */
10981 removeConfig(full_name);
10982 sdsfree(full_name);
10983 }
10984}
10985
10986/* Load all the modules in the server.loadmodule_queue list, which is
10987 * populated by `loadmodule` directives in the configuration file.
10988 * We can't load modules directly when processing the configuration file
10989 * because the server must be fully initialized before loading modules.
10990 *
10991 * The function aborts the server on errors, since to start with missing
10992 * modules is not considered sane: clients may rely on the existence of
10993 * given commands, loading AOF also may need some modules to exist, and
10994 * if this instance is a slave, it must understand commands from master. */
10995void moduleLoadFromQueue(void) {
10996 listIter li;
10997 listNode *ln;
10998
10999 listRewind(server.loadmodule_queue,&li);
11000 while((ln = listNext(&li))) {
11001 struct moduleLoadQueueEntry *loadmod = ln->value;
11002 if (moduleLoad(loadmod->path,(void **)loadmod->argv,loadmod->argc, 0)
11003 == C_ERR)
11004 {
11005 serverLog(LL_WARNING,
11006 "Can't load module from %s: server aborting",
11007 loadmod->path);
11008 exit(1);
11009 }
11010 moduleLoadQueueEntryFree(loadmod);
11011 listDelNode(server.loadmodule_queue, ln);
11012 }
11013 if (dictSize(server.module_configs_queue)) {
11014 serverLog(LL_WARNING, "Module Configuration detected without loadmodule directive or no ApplyConfig call: aborting");
11015 exit(1);
11016 }
11017}
11018
11019void moduleFreeModuleStructure(struct RedisModule *module) {
11020 listRelease(module->types);
11021 listRelease(module->filters);
11022 listRelease(module->usedby);
11023 listRelease(module->using);
11024 listRelease(module->module_configs);
11025 sdsfree(module->name);
11026 moduleLoadQueueEntryFree(module->loadmod);
11027 zfree(module);
11028}
11029
11030/* Free the command registered with the specified module.
11031 * On success C_OK is returned, otherwise C_ERR is returned.
11032 *
11033 * Note that caller needs to handle the deletion of the command table dict,
11034 * and after that needs to free the command->fullname and the command itself.
11035 */
11036int moduleFreeCommand(struct RedisModule *module, struct redisCommand *cmd) {
11037 if (cmd->proc != RedisModuleCommandDispatcher)
11038 return C_ERR;
11039
11040 RedisModuleCommand *cp = cmd->module_cmd;
11041 if (cp->module != module)
11042 return C_ERR;
11043
11044 /* Free everything except cmd->fullname and cmd itself. */
11045 for (int j = 0; j < cmd->key_specs_num; j++) {
11046 if (cmd->key_specs[j].notes)
11047 zfree((char *)cmd->key_specs[j].notes);
11048 if (cmd->key_specs[j].begin_search_type == KSPEC_BS_KEYWORD)
11049 zfree((char *)cmd->key_specs[j].bs.keyword.keyword);
11050 }
11051 if (cmd->key_specs != cmd->key_specs_static)
11052 zfree(cmd->key_specs);
11053 for (int j = 0; cmd->tips && cmd->tips[j]; j++)
11054 zfree((char *)cmd->tips[j]);
11055 for (int j = 0; cmd->history && cmd->history[j].since; j++) {
11056 zfree((char *)cmd->history[j].since);
11057 zfree((char *)cmd->history[j].changes);
11058 }
11059 zfree((char *)cmd->summary);
11060 zfree((char *)cmd->since);
11061 zfree((char *)cmd->deprecated_since);
11062 zfree((char *)cmd->complexity);
11063 if (cmd->latency_histogram) {
11064 hdr_close(cmd->latency_histogram);
11065 cmd->latency_histogram = NULL;
11066 }
11067 zfree(cmd->args);
11068 zfree(cp);
11069
11070 if (cmd->subcommands_dict) {
11071 dictEntry *de;
11072 dictIterator *di = dictGetSafeIterator(cmd->subcommands_dict);
11073 while ((de = dictNext(di)) != NULL) {
11074 struct redisCommand *sub = dictGetVal(de);
11075 if (moduleFreeCommand(module, sub) != C_OK) continue;
11076
11077 serverAssert(dictDelete(cmd->subcommands_dict, sub->declared_name) == DICT_OK);
11078 sdsfree((sds)sub->declared_name);
11079 sdsfree(sub->fullname);
11080 zfree(sub);
11081 }
11082 dictReleaseIterator(di);
11083 dictRelease(cmd->subcommands_dict);
11084 }
11085
11086 return C_OK;
11087}
11088
11089void moduleUnregisterCommands(struct RedisModule *module) {
11090 /* Unregister all the commands registered by this module. */
11091 dictIterator *di = dictGetSafeIterator(server.commands);
11092 dictEntry *de;
11093 while ((de = dictNext(di)) != NULL) {
11094 struct redisCommand *cmd = dictGetVal(de);
11095 if (moduleFreeCommand(module, cmd) != C_OK) continue;
11096
11097 serverAssert(dictDelete(server.commands, cmd->fullname) == DICT_OK);
11098 serverAssert(dictDelete(server.orig_commands, cmd->fullname) == DICT_OK);
11099 sdsfree((sds)cmd->declared_name);
11100 sdsfree(cmd->fullname);
11101 zfree(cmd);
11102 }
11103 dictReleaseIterator(di);
11104}
11105
11106/* We parse argv to add sds "NAME VALUE" pairs to the server.module_configs_queue list of configs.
11107 * We also increment the module_argv pointer to just after ARGS if there are args, otherwise
11108 * we set it to NULL */
11109int parseLoadexArguments(RedisModuleString ***module_argv, int *module_argc) {
11110 int args_specified = 0;
11111 RedisModuleString **argv = *module_argv;
11112 int argc = *module_argc;
11113 for (int i = 0; i < argc; i++) {
11114 char *arg_val = argv[i]->ptr;
11115 if (!strcasecmp(arg_val, "CONFIG")) {
11116 if (i + 2 >= argc) {
11117 serverLog(LL_NOTICE, "CONFIG specified without name value pair");
11118 return REDISMODULE_ERR;
11119 }
11120 sds name = sdsdup(argv[i + 1]->ptr);
11121 sds value = sdsdup(argv[i + 2]->ptr);
11122 if (!dictReplace(server.module_configs_queue, name, value)) sdsfree(name);
11123 i += 2;
11124 } else if (!strcasecmp(arg_val, "ARGS")) {
11125 args_specified = 1;
11126 i++;
11127 if (i >= argc) {
11128 *module_argv = NULL;
11129 *module_argc = 0;
11130 } else {
11131 *module_argv = argv + i;
11132 *module_argc = argc - i;
11133 }
11134 break;
11135 } else {
11136 serverLog(LL_NOTICE, "Syntax Error from arguments to loadex around %s.", arg_val);
11137 return REDISMODULE_ERR;
11138 }
11139 }
11140 if (!args_specified) {
11141 *module_argv = NULL;
11142 *module_argc = 0;
11143 }
11144 return REDISMODULE_OK;
11145}
11146
11147/* Load a module and initialize it. On success C_OK is returned, otherwise
11148 * C_ERR is returned. */
11149int moduleLoad(const char *path, void **module_argv, int module_argc, int is_loadex) {
11150 int (*onload)(void *, void **, int);
11151 void *handle;
11152
11153 struct stat st;
11154 if (stat(path, &st) == 0) {
11155 /* This check is best effort */
11156 if (!(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
11157 serverLog(LL_WARNING, "Module %s failed to load: It does not have execute permissions.", path);
11158 return C_ERR;
11159 }
11160 }
11161
11162 handle = dlopen(path,RTLD_NOW|RTLD_LOCAL);
11163 if (handle == NULL) {
11164 serverLog(LL_WARNING, "Module %s failed to load: %s", path, dlerror());
11165 return C_ERR;
11166 }
11167 onload = (int (*)(void *, void **, int))(unsigned long) dlsym(handle,"RedisModule_OnLoad");
11168 if (onload == NULL) {
11169 dlclose(handle);
11170 serverLog(LL_WARNING,
11171 "Module %s does not export RedisModule_OnLoad() "
11172 "symbol. Module not loaded.",path);
11173 return C_ERR;
11174 }
11175 RedisModuleCtx ctx;
11176 moduleCreateContext(&ctx, NULL, REDISMODULE_CTX_TEMP_CLIENT); /* We pass NULL since we don't have a module yet. */
11177 selectDb(ctx.client, 0);
11178 if (onload((void*)&ctx,module_argv,module_argc) == REDISMODULE_ERR) {
11179 serverLog(LL_WARNING,
11180 "Module %s initialization failed. Module not loaded",path);
11181 if (ctx.module) {
11182 moduleUnregisterCommands(ctx.module);
11183 moduleUnregisterSharedAPI(ctx.module);
11184 moduleUnregisterUsedAPI(ctx.module);
11185 moduleRemoveConfigs(ctx.module);
11186 moduleFreeModuleStructure(ctx.module);
11187 }
11188 moduleFreeContext(&ctx);
11189 dlclose(handle);
11190 return C_ERR;
11191 }
11192
11193 /* Redis module loaded! Register it. */
11194 dictAdd(modules,ctx.module->name,ctx.module);
11195 ctx.module->blocked_clients = 0;
11196 ctx.module->handle = handle;
11197 ctx.module->loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry));
11198 ctx.module->loadmod->path = sdsnew(path);
11199 ctx.module->loadmod->argv = module_argc ? zmalloc(sizeof(robj*)*module_argc) : NULL;
11200 ctx.module->loadmod->argc = module_argc;
11201 for (int i = 0; i < module_argc; i++) {
11202 ctx.module->loadmod->argv[i] = module_argv[i];
11203 incrRefCount(ctx.module->loadmod->argv[i]);
11204 }
11205
11206 serverLog(LL_NOTICE,"Module '%s' loaded from %s",ctx.module->name,path);
11207
11208 if (listLength(ctx.module->module_configs) && !ctx.module->configs_initialized) {
11209 serverLogRaw(LL_WARNING, "Module Configurations were not set, likely a missing LoadConfigs call. Unloading the module.");
11210 moduleUnload(ctx.module->name);
11211 moduleFreeContext(&ctx);
11212 return C_ERR;
11213 }
11214
11215 if (is_loadex && dictSize(server.module_configs_queue)) {
11216 serverLogRaw(LL_WARNING, "Loadex configurations were not applied, likely due to invalid arguments. Unloading the module.");
11217 moduleUnload(ctx.module->name);
11218 moduleFreeContext(&ctx);
11219 return C_ERR;
11220 }
11221
11222 /* Fire the loaded modules event. */
11223 moduleFireServerEvent(REDISMODULE_EVENT_MODULE_CHANGE,
11224 REDISMODULE_SUBEVENT_MODULE_LOADED,
11225 ctx.module);
11226
11227 moduleFreeContext(&ctx);
11228 return C_OK;
11229}
11230
11231/* Unload the module registered with the specified name. On success
11232 * C_OK is returned, otherwise C_ERR is returned and errno is set
11233 * to the following values depending on the type of error:
11234 *
11235 * * ENONET: No such module having the specified name.
11236 * * EBUSY: The module exports a new data type and can only be reloaded.
11237 * * EPERM: The module exports APIs which are used by other module.
11238 * * EAGAIN: The module has blocked clients.
11239 * * EINPROGRESS: The module holds timer not fired.
11240 * * ECANCELED: Unload module error. */
11241int moduleUnload(sds name) {
11242 struct RedisModule *module = dictFetchValue(modules,name);
11243
11244 if (module == NULL) {
11245 errno = ENOENT;
11246 return C_ERR;
11247 } else if (listLength(module->types)) {
11248 errno = EBUSY;
11249 return C_ERR;
11250 } else if (listLength(module->usedby)) {
11251 errno = EPERM;
11252 return C_ERR;
11253 } else if (module->blocked_clients) {
11254 errno = EAGAIN;
11255 return C_ERR;
11256 } else if (moduleHoldsTimer(module)) {
11257 errno = EINPROGRESS;
11258 return C_ERR;
11259 }
11260
11261 /* Give module a chance to clean up. */
11262 int (*onunload)(void *);
11263 onunload = (int (*)(void *))(unsigned long) dlsym(module->handle, "RedisModule_OnUnload");
11264 if (onunload) {
11265 RedisModuleCtx ctx;
11266 moduleCreateContext(&ctx, module, REDISMODULE_CTX_TEMP_CLIENT);
11267 int unload_status = onunload((void*)&ctx);
11268 moduleFreeContext(&ctx);
11269
11270 if (unload_status == REDISMODULE_ERR) {
11271 serverLog(LL_WARNING, "Module %s OnUnload failed. Unload canceled.", name);
11272 errno = ECANCELED;
11273 return C_ERR;
11274 }
11275 }
11276
11277 moduleFreeAuthenticatedClients(module);
11278 moduleUnregisterCommands(module);
11279 moduleUnregisterSharedAPI(module);
11280 moduleUnregisterUsedAPI(module);
11281 moduleUnregisterFilters(module);
11282 moduleRemoveConfigs(module);
11283
11284 /* Remove any notification subscribers this module might have */
11285 moduleUnsubscribeNotifications(module);
11286 moduleUnsubscribeAllServerEvents(module);
11287
11288 /* Unload the dynamic library. */
11289 if (dlclose(module->handle) == -1) {
11290 char *error = dlerror();
11291 if (error == NULL) error = "Unknown error";
11292 serverLog(LL_WARNING,"Error when trying to close the %s module: %s",
11293 module->name, error);
11294 }
11295
11296 /* Fire the unloaded modules event. */
11297 moduleFireServerEvent(REDISMODULE_EVENT_MODULE_CHANGE,
11298 REDISMODULE_SUBEVENT_MODULE_UNLOADED,
11299 module);
11300
11301 /* Remove from list of modules. */
11302 serverLog(LL_NOTICE,"Module %s unloaded",module->name);
11303 dictDelete(modules,module->name);
11304 module->name = NULL; /* The name was already freed by dictDelete(). */
11305 moduleFreeModuleStructure(module);
11306
11307 return C_OK;
11308}
11309
11310void modulePipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) {
11311 UNUSED(el);
11312 UNUSED(fd);
11313 UNUSED(mask);
11314 UNUSED(privdata);
11315
11316 char buf[128];
11317 while (read(fd, buf, sizeof(buf)) == sizeof(buf));
11318
11319 /* Handle event loop events if pipe was written from event loop API */
11320 eventLoopHandleOneShotEvents();
11321}
11322
11323/* Helper function for the MODULE and HELLO command: send the list of the
11324 * loaded modules to the client. */
11325void addReplyLoadedModules(client *c) {
11326 dictIterator *di = dictGetIterator(modules);
11327 dictEntry *de;
11328
11329 addReplyArrayLen(c,dictSize(modules));
11330 while ((de = dictNext(di)) != NULL) {
11331 sds name = dictGetKey(de);
11332 struct RedisModule *module = dictGetVal(de);
11333 sds path = module->loadmod->path;
11334 addReplyMapLen(c,4);
11335 addReplyBulkCString(c,"name");
11336 addReplyBulkCBuffer(c,name,sdslen(name));
11337 addReplyBulkCString(c,"ver");
11338 addReplyLongLong(c,module->ver);
11339 addReplyBulkCString(c,"path");
11340 addReplyBulkCBuffer(c,path,sdslen(path));
11341 addReplyBulkCString(c,"args");
11342 addReplyArrayLen(c,module->loadmod->argc);
11343 for (int i = 0; i < module->loadmod->argc; i++) {
11344 addReplyBulk(c,module->loadmod->argv[i]);
11345 }
11346 }
11347 dictReleaseIterator(di);
11348}
11349
11350/* Helper for genModulesInfoString(): given a list of modules, return
11351 * an SDS string in the form "[modulename|modulename2|...]" */
11352sds genModulesInfoStringRenderModulesList(list *l) {
11353 listIter li;
11354 listNode *ln;
11355 listRewind(l,&li);
11356 sds output = sdsnew("[");
11357 while((ln = listNext(&li))) {
11358 RedisModule *module = ln->value;
11359 output = sdscat(output,module->name);
11360 if (ln != listLast(l))
11361 output = sdscat(output,"|");
11362 }
11363 output = sdscat(output,"]");
11364 return output;
11365}
11366
11367/* Helper for genModulesInfoString(): render module options as an SDS string. */
11368sds genModulesInfoStringRenderModuleOptions(struct RedisModule *module) {
11369 sds output = sdsnew("[");
11370 if (module->options & REDISMODULE_OPTIONS_HANDLE_IO_ERRORS)
11371 output = sdscat(output,"handle-io-errors|");
11372 if (module->options & REDISMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD)
11373 output = sdscat(output,"handle-repl-async-load|");
11374 if (module->options & REDISMODULE_OPTION_NO_IMPLICIT_SIGNAL_MODIFIED)
11375 output = sdscat(output,"no-implicit-signal-modified|");
11376 output = sdstrim(output,"|");
11377 output = sdscat(output,"]");
11378 return output;
11379}
11380
11381
11382/* Helper function for the INFO command: adds loaded modules as to info's
11383 * output.
11384 *
11385 * After the call, the passed sds info string is no longer valid and all the
11386 * references must be substituted with the new pointer returned by the call. */
11387sds genModulesInfoString(sds info) {
11388 dictIterator *di = dictGetIterator(modules);
11389 dictEntry *de;
11390
11391 while ((de = dictNext(di)) != NULL) {
11392 sds name = dictGetKey(de);
11393 struct RedisModule *module = dictGetVal(de);
11394
11395 sds usedby = genModulesInfoStringRenderModulesList(module->usedby);
11396 sds using = genModulesInfoStringRenderModulesList(module->using);
11397 sds options = genModulesInfoStringRenderModuleOptions(module);
11398 info = sdscatfmt(info,
11399 "module:name=%S,ver=%i,api=%i,filters=%i,"
11400 "usedby=%S,using=%S,options=%S\r\n",
11401 name, module->ver, module->apiver,
11402 (int)listLength(module->filters), usedby, using, options);
11403 sdsfree(usedby);
11404 sdsfree(using);
11405 sdsfree(options);
11406 }
11407 dictReleaseIterator(di);
11408 return info;
11409}
11410
11411/* --------------------------------------------------------------------------
11412 * Module Configurations API internals
11413 * -------------------------------------------------------------------------- */
11414
11415/* Check if the configuration name is already registered */
11416int isModuleConfigNameRegistered(RedisModule *module, sds name) {
11417 listNode *match = listSearchKey(module->module_configs, (void *) name);
11418 return match != NULL;
11419}
11420
11421/* Assert that the flags passed into the RM_RegisterConfig Suite are valid */
11422int moduleVerifyConfigFlags(unsigned int flags, configType type) {
11423 if ((flags & ~(REDISMODULE_CONFIG_DEFAULT
11424 | REDISMODULE_CONFIG_IMMUTABLE
11425 | REDISMODULE_CONFIG_SENSITIVE
11426 | REDISMODULE_CONFIG_HIDDEN
11427 | REDISMODULE_CONFIG_PROTECTED
11428 | REDISMODULE_CONFIG_DENY_LOADING
11429 | REDISMODULE_CONFIG_BITFLAGS
11430 | REDISMODULE_CONFIG_MEMORY))) {
11431 serverLogRaw(LL_WARNING, "Invalid flag(s) for configuration");
11432 return REDISMODULE_ERR;
11433 }
11434 if (type != NUMERIC_CONFIG && flags & REDISMODULE_CONFIG_MEMORY) {
11435 serverLogRaw(LL_WARNING, "Numeric flag provided for non-numeric configuration.");
11436 return REDISMODULE_ERR;
11437 }
11438 if (type != ENUM_CONFIG && flags & REDISMODULE_CONFIG_BITFLAGS) {
11439 serverLogRaw(LL_WARNING, "Enum flag provided for non-enum configuration.");
11440 return REDISMODULE_ERR;
11441 }
11442 return REDISMODULE_OK;
11443}
11444
11445int moduleVerifyConfigName(sds name) {
11446 if (sdslen(name) == 0) {
11447 serverLogRaw(LL_WARNING, "Module config names cannot be an empty string.");
11448 return REDISMODULE_ERR;
11449 }
11450 for (size_t i = 0 ; i < sdslen(name) ; ++i) {
11451 char curr_char = name[i];
11452 if ((curr_char >= 'a' && curr_char <= 'z') ||
11453 (curr_char >= 'A' && curr_char <= 'Z') ||
11454 (curr_char >= '0' && curr_char <= '9') ||
11455 (curr_char == '_') || (curr_char == '-'))
11456 {
11457 continue;
11458 }
11459 serverLog(LL_WARNING, "Invalid character %c in Module Config name %s.", curr_char, name);
11460 return REDISMODULE_ERR;
11461 }
11462 return REDISMODULE_OK;
11463}
11464
11465/* This is a series of set functions for each type that act as dispatchers for
11466 * config.c to call module set callbacks. */
11467#define CONFIG_ERR_SIZE 256
11468static char configerr[CONFIG_ERR_SIZE];
11469static void propagateErrorString(RedisModuleString *err_in, const char **err) {
11470 if (err_in) {
11471 strncpy(configerr, err_in->ptr, CONFIG_ERR_SIZE);
11472 configerr[CONFIG_ERR_SIZE - 1] = '\0';
11473 decrRefCount(err_in);
11474 *err = configerr;
11475 }
11476}
11477
11478int setModuleBoolConfig(ModuleConfig *config, int val, const char **err) {
11479 RedisModuleString *error = NULL;
11480 int return_code = config->set_fn.set_bool(config->name, val, config->privdata, &error);
11481 propagateErrorString(error, err);
11482 return return_code == REDISMODULE_OK ? 1 : 0;
11483}
11484
11485int setModuleStringConfig(ModuleConfig *config, sds strval, const char **err) {
11486 RedisModuleString *error = NULL;
11487 RedisModuleString *new = createStringObject(strval, sdslen(strval));
11488 int return_code = config->set_fn.set_string(config->name, new, config->privdata, &error);
11489 propagateErrorString(error, err);
11490 decrRefCount(new);
11491 return return_code == REDISMODULE_OK ? 1 : 0;
11492}
11493
11494int setModuleEnumConfig(ModuleConfig *config, int val, const char **err) {
11495 RedisModuleString *error = NULL;
11496 int return_code = config->set_fn.set_enum(config->name, val, config->privdata, &error);
11497 propagateErrorString(error, err);
11498 return return_code == REDISMODULE_OK ? 1 : 0;
11499}
11500
11501int setModuleNumericConfig(ModuleConfig *config, long long val, const char **err) {
11502 RedisModuleString *error = NULL;
11503 int return_code = config->set_fn.set_numeric(config->name, val, config->privdata, &error);
11504 propagateErrorString(error, err);
11505 return return_code == REDISMODULE_OK ? 1 : 0;
11506}
11507
11508/* This is a series of get functions for each type that act as dispatchers for
11509 * config.c to call module set callbacks. */
11510int getModuleBoolConfig(ModuleConfig *module_config) {
11511 return module_config->get_fn.get_bool(module_config->name, module_config->privdata);
11512}
11513
11514sds getModuleStringConfig(ModuleConfig *module_config) {
11515 RedisModuleString *val = module_config->get_fn.get_string(module_config->name, module_config->privdata);
11516 return val ? sdsdup(val->ptr) : NULL;
11517}
11518
11519int getModuleEnumConfig(ModuleConfig *module_config) {
11520 return module_config->get_fn.get_enum(module_config->name, module_config->privdata);
11521}
11522
11523long long getModuleNumericConfig(ModuleConfig *module_config) {
11524 return module_config->get_fn.get_numeric(module_config->name, module_config->privdata);
11525}
11526
11527/* This function takes a module and a list of configs stored as sds NAME VALUE pairs.
11528 * It attempts to call set on each of these configs. */
11529int loadModuleConfigs(RedisModule *module) {
11530 listIter li;
11531 listNode *ln;
11532 const char *err = NULL;
11533 listRewind(module->module_configs, &li);
11534 while ((ln = listNext(&li))) {
11535 ModuleConfig *module_config = listNodeValue(ln);
11536 sds config_name = sdscatfmt(sdsempty(), "%s.%s", module->name, module_config->name);
11537 dictEntry *config_argument = dictFind(server.module_configs_queue, config_name);
11538 if (config_argument) {
11539 if (!performModuleConfigSetFromName(dictGetKey(config_argument), dictGetVal(config_argument), &err)) {
11540 serverLog(LL_WARNING, "Issue during loading of configuration %s : %s", (sds) dictGetKey(config_argument), err);
11541 sdsfree(config_name);
11542 dictEmpty(server.module_configs_queue, NULL);
11543 return REDISMODULE_ERR;
11544 }
11545 } else {
11546 if (!performModuleConfigSetDefaultFromName(config_name, &err)) {
11547 serverLog(LL_WARNING, "Issue attempting to set default value of configuration %s : %s", module_config->name, err);
11548 sdsfree(config_name);
11549 dictEmpty(server.module_configs_queue, NULL);
11550 return REDISMODULE_ERR;
11551 }
11552 }
11553 dictDelete(server.module_configs_queue, config_name);
11554 sdsfree(config_name);
11555 }
11556 module->configs_initialized = 1;
11557 return REDISMODULE_OK;
11558}
11559
11560/* Add module_config to the list if the apply and privdata do not match one already in it. */
11561void addModuleConfigApply(list *module_configs, ModuleConfig *module_config) {
11562 if (!module_config->apply_fn) return;
11563 listIter li;
11564 listNode *ln;
11565 ModuleConfig *pending_apply;
11566 listRewind(module_configs, &li);
11567 while ((ln = listNext(&li))) {
11568 pending_apply = listNodeValue(ln);
11569 if (pending_apply->apply_fn == module_config->apply_fn && pending_apply->privdata == module_config->privdata) {
11570 return;
11571 }
11572 }
11573 listAddNodeTail(module_configs, module_config);
11574}
11575
11576/* Call apply on all module configs specified in set, if an apply function was specified at registration time. */
11577int moduleConfigApplyConfig(list *module_configs, const char **err, const char **err_arg_name) {
11578 if (!listLength(module_configs)) return 1;
11579 listIter li;
11580 listNode *ln;
11581 ModuleConfig *module_config;
11582 RedisModuleString *error = NULL;
11583 RedisModuleCtx ctx;
11584
11585 listRewind(module_configs, &li);
11586 while ((ln = listNext(&li))) {
11587 module_config = listNodeValue(ln);
11588 moduleCreateContext(&ctx, module_config->module, REDISMODULE_CTX_NONE);
11589 if (module_config->apply_fn(&ctx, module_config->privdata, &error)) {
11590 if (err_arg_name) *err_arg_name = module_config->name;
11591 propagateErrorString(error, err);
11592 moduleFreeContext(&ctx);
11593 return 0;
11594 }
11595 moduleFreeContext(&ctx);
11596 }
11597 return 1;
11598}
11599
11600/* --------------------------------------------------------------------------
11601 * ## Module Configurations API
11602 * -------------------------------------------------------------------------- */
11603
11604/* Create a module config object. */
11605ModuleConfig *createModuleConfig(sds name, RedisModuleConfigApplyFunc apply_fn, void *privdata, RedisModule *module) {
11606 ModuleConfig *new_config = zmalloc(sizeof(ModuleConfig));
11607 new_config->name = sdsdup(name);
11608 new_config->apply_fn = apply_fn;
11609 new_config->privdata = privdata;
11610 new_config->module = module;
11611 return new_config;
11612}
11613
11614int moduleConfigValidityCheck(RedisModule *module, sds name, unsigned int flags, configType type) {
11615 if (moduleVerifyConfigFlags(flags, type) || moduleVerifyConfigName(name)) {
11616 errno = EINVAL;
11617 return REDISMODULE_ERR;
11618 }
11619 if (isModuleConfigNameRegistered(module, name)) {
11620 serverLog(LL_WARNING, "Configuration by the name: %s already registered", name);
11621 errno = EALREADY;
11622 return REDISMODULE_ERR;
11623 }
11624 return REDISMODULE_OK;
11625}
11626
11627unsigned int maskModuleConfigFlags(unsigned int flags) {
11628 unsigned int new_flags = 0;
11629 if (flags & REDISMODULE_CONFIG_DEFAULT) new_flags |= MODIFIABLE_CONFIG;
11630 if (flags & REDISMODULE_CONFIG_IMMUTABLE) new_flags |= IMMUTABLE_CONFIG;
11631 if (flags & REDISMODULE_CONFIG_HIDDEN) new_flags |= HIDDEN_CONFIG;
11632 if (flags & REDISMODULE_CONFIG_PROTECTED) new_flags |= PROTECTED_CONFIG;
11633 if (flags & REDISMODULE_CONFIG_DENY_LOADING) new_flags |= DENY_LOADING_CONFIG;
11634 return new_flags;
11635}
11636
11637unsigned int maskModuleNumericConfigFlags(unsigned int flags) {
11638 unsigned int new_flags = 0;
11639 if (flags & REDISMODULE_CONFIG_MEMORY) new_flags |= MEMORY_CONFIG;
11640 return new_flags;
11641}
11642
11643unsigned int maskModuleEnumConfigFlags(unsigned int flags) {
11644 unsigned int new_flags = 0;
11645 if (flags & REDISMODULE_CONFIG_BITFLAGS) new_flags |= MULTI_ARG_CONFIG;
11646 return new_flags;
11647}
11648
11649/* Create a string config that Redis users can interact with via the Redis config file,
11650 * `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands.
11651 *
11652 * The actual config value is owned by the module, and the `getfn`, `setfn` and optional
11653 * `applyfn` callbacks that are provided to Redis in order to access or manipulate the
11654 * value. The `getfn` callback retrieves the value from the module, while the `setfn`
11655 * callback provides a value to be stored into the module config.
11656 * The optional `applyfn` callback is called after a `CONFIG SET` command modified one or
11657 * more configs using the `setfn` callback and can be used to atomically apply a config
11658 * after several configs were changed together.
11659 * If there are multiple configs with `applyfn` callbacks set by a single `CONFIG SET`
11660 * command, they will be deduplicated if their `applyfn` function and `privdata` pointers
11661 * are identical, and the callback will only be run once.
11662 * Both the `setfn` and `applyfn` can return an error if the provided value is invalid or
11663 * cannot be used.
11664 * The config also declares a type for the value that is validated by Redis and
11665 * provided to the module. The config system provides the following types:
11666 *
11667 * * Redis String: Binary safe string data.
11668 * * Enum: One of a finite number of string tokens, provided during registration.
11669 * * Numeric: 64 bit signed integer, which also supports min and max values.
11670 * * Bool: Yes or no value.
11671 *
11672 * The `setfn` callback is expected to return REDISMODULE_OK when the value is successfully
11673 * applied. It can also return REDISMODULE_ERR if the value can't be applied, and the
11674 * *err pointer can be set with a RedisModuleString error message to provide to the client.
11675 * This RedisModuleString will be freed by redis after returning from the set callback.
11676 *
11677 * All configs are registered with a name, a type, a default value, private data that is made
11678 * available in the callbacks, as well as several flags that modify the behavior of the config.
11679 * The name must only contain alphanumeric characters or dashes. The supported flags are:
11680 *
11681 * * REDISMODULE_CONFIG_DEFAULT: The default flags for a config. This creates a config that can be modified after startup.
11682 * * REDISMODULE_CONFIG_IMMUTABLE: This config can only be provided loading time.
11683 * * REDISMODULE_CONFIG_SENSITIVE: The value stored in this config is redacted from all logging.
11684 * * REDISMODULE_CONFIG_HIDDEN: The name is hidden from `CONFIG GET` with pattern matching.
11685 * * REDISMODULE_CONFIG_PROTECTED: This config will be only be modifiable based off the value of enable-protected-configs.
11686 * * REDISMODULE_CONFIG_DENY_LOADING: This config is not modifiable while the server is loading data.
11687 * * REDISMODULE_CONFIG_MEMORY: For numeric configs, this config will convert data unit notations into their byte equivalent.
11688 * * REDISMODULE_CONFIG_BITFLAGS: For enum configs, this config will allow multiple entries to be combined as bit flags.
11689 *
11690 * Default values are used on startup to set the value if it is not provided via the config file
11691 * or command line. Default values are also used to compare to on a config rewrite.
11692 *
11693 * Notes:
11694 *
11695 * 1. On string config sets that the string passed to the set callback will be freed after execution and the module must retain it.
11696 * 2. On string config gets the string will not be consumed and will be valid after execution.
11697 *
11698 * Example implementation:
11699 *
11700 * RedisModuleString *strval;
11701 * int adjustable = 1;
11702 * RedisModuleString *getStringConfigCommand(const char *name, void *privdata) {
11703 * return strval;
11704 * }
11705 *
11706 * int setStringConfigCommand(const char *name, RedisModuleString *new, void *privdata, RedisModuleString **err) {
11707 * if (adjustable) {
11708 * RedisModule_Free(strval);
11709 * RedisModule_RetainString(NULL, new);
11710 * strval = new;
11711 * return REDISMODULE_OK;
11712 * }
11713 * *err = RedisModule_CreateString(NULL, "Not adjustable.", 15);
11714 * return REDISMODULE_ERR;
11715 * }
11716 * ...
11717 * RedisModule_RegisterStringConfig(ctx, "string", NULL, REDISMODULE_CONFIG_DEFAULT, getStringConfigCommand, setStringConfigCommand, NULL, NULL);
11718 *
11719 * If the registration fails, REDISMODULE_ERR is returned and one of the following
11720 * errno is set:
11721 * * EINVAL: The provided flags are invalid for the registration or the name of the config contains invalid characters.
11722 * * EALREADY: The provided configuration name is already used. */
11723int RM_RegisterStringConfig(RedisModuleCtx *ctx, const char *name, const char *default_val, unsigned int flags, RedisModuleConfigGetStringFunc getfn, RedisModuleConfigSetStringFunc setfn, RedisModuleConfigApplyFunc applyfn, void *privdata) {
11724 RedisModule *module = ctx->module;
11725 sds config_name = sdsnew(name);
11726 if (moduleConfigValidityCheck(module, config_name, flags, NUMERIC_CONFIG)) {
11727 sdsfree(config_name);
11728 return REDISMODULE_ERR;
11729 }
11730 ModuleConfig *new_config = createModuleConfig(config_name, applyfn, privdata, module);
11731 sdsfree(config_name);
11732 new_config->get_fn.get_string = getfn;
11733 new_config->set_fn.set_string = setfn;
11734 listAddNodeTail(module->module_configs, new_config);
11735 flags = maskModuleConfigFlags(flags);
11736 addModuleStringConfig(module->name, name, flags, new_config, default_val ? sdsnew(default_val) : NULL);
11737 return REDISMODULE_OK;
11738}
11739
11740/* Create a bool config that server clients can interact with via the
11741 * `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands. See
11742 * RedisModule_RegisterStringConfig for detailed information about configs. */
11743int RM_RegisterBoolConfig(RedisModuleCtx *ctx, const char *name, int default_val, unsigned int flags, RedisModuleConfigGetBoolFunc getfn, RedisModuleConfigSetBoolFunc setfn, RedisModuleConfigApplyFunc applyfn, void *privdata) {
11744 RedisModule *module = ctx->module;
11745 sds config_name = sdsnew(name);
11746 if (moduleConfigValidityCheck(module, config_name, flags, BOOL_CONFIG)) {
11747 sdsfree(config_name);
11748 return REDISMODULE_ERR;
11749 }
11750 ModuleConfig *new_config = createModuleConfig(config_name, applyfn, privdata, module);
11751 sdsfree(config_name);
11752 new_config->get_fn.get_bool = getfn;
11753 new_config->set_fn.set_bool = setfn;
11754 listAddNodeTail(module->module_configs, new_config);
11755 flags = maskModuleConfigFlags(flags);
11756 addModuleBoolConfig(module->name, name, flags, new_config, default_val);
11757 return REDISMODULE_OK;
11758}
11759
11760/*
11761 * Create an enum config that server clients can interact with via the
11762 * `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands.
11763 * Enum configs are a set of string tokens to corresponding integer values, where
11764 * the string value is exposed to Redis clients but the value passed Redis and the
11765 * module is the integer value. These values are defined in enum_values, an array
11766 * of null-terminated c strings, and int_vals, an array of enum values who has an
11767 * index partner in enum_values.
11768 * Example Implementation:
11769 * const char *enum_vals[3] = {"first", "second", "third"};
11770 * const int int_vals[3] = {0, 2, 4};
11771 * int enum_val = 0;
11772 *
11773 * int getEnumConfigCommand(const char *name, void *privdata) {
11774 * return enum_val;
11775 * }
11776 *
11777 * int setEnumConfigCommand(const char *name, int val, void *privdata, const char **err) {
11778 * enum_val = val;
11779 * return REDISMODULE_OK;
11780 * }
11781 * ...
11782 * RedisModule_RegisterEnumConfig(ctx, "enum", 0, REDISMODULE_CONFIG_DEFAULT, enum_vals, int_vals, 3, getEnumConfigCommand, setEnumConfigCommand, NULL, NULL);
11783 *
11784 * Note that you can use REDISMODULE_CONFIG_BITFLAGS so that multiple enum string
11785 * can be combined into one integer as bit flags, in which case you may want to
11786 * sort your enums so that the preferred combinations are present first.
11787 *
11788 * See RedisModule_RegisterStringConfig for detailed general information about configs. */
11789int RM_RegisterEnumConfig(RedisModuleCtx *ctx, const char *name, int default_val, unsigned int flags, const char **enum_values, const int *int_values, int num_enum_vals, RedisModuleConfigGetEnumFunc getfn, RedisModuleConfigSetEnumFunc setfn, RedisModuleConfigApplyFunc applyfn, void *privdata) {
11790 RedisModule *module = ctx->module;
11791 sds config_name = sdsnew(name);
11792 if (moduleConfigValidityCheck(module, config_name, flags, ENUM_CONFIG)) {
11793 sdsfree(config_name);
11794 return REDISMODULE_ERR;
11795 }
11796 ModuleConfig *new_config = createModuleConfig(config_name, applyfn, privdata, module);
11797 sdsfree(config_name);
11798 new_config->get_fn.get_enum = getfn;
11799 new_config->set_fn.set_enum = setfn;
11800 configEnum *enum_vals = zmalloc((num_enum_vals + 1) * sizeof(configEnum));
11801 for (int i = 0; i < num_enum_vals; i++) {
11802 enum_vals[i].name = zstrdup(enum_values[i]);
11803 enum_vals[i].val = int_values[i];
11804 }
11805 enum_vals[num_enum_vals].name = NULL;
11806 enum_vals[num_enum_vals].val = 0;
11807 listAddNodeTail(module->module_configs, new_config);
11808 flags = maskModuleConfigFlags(flags) | maskModuleEnumConfigFlags(flags);
11809 addModuleEnumConfig(module->name, name, flags, new_config, default_val, enum_vals);
11810 return REDISMODULE_OK;
11811}
11812
11813/*
11814 * Create an integer config that server clients can interact with via the
11815 * `CONFIG SET`, `CONFIG GET`, and `CONFIG REWRITE` commands. See
11816 * RedisModule_RegisterStringConfig for detailed information about configs. */
11817int RM_RegisterNumericConfig(RedisModuleCtx *ctx, const char *name, long long default_val, unsigned int flags, long long min, long long max, RedisModuleConfigGetNumericFunc getfn, RedisModuleConfigSetNumericFunc setfn, RedisModuleConfigApplyFunc applyfn, void *privdata) {
11818 RedisModule *module = ctx->module;
11819 sds config_name = sdsnew(name);
11820 if (moduleConfigValidityCheck(module, config_name, flags, NUMERIC_CONFIG)) {
11821 sdsfree(config_name);
11822 return REDISMODULE_ERR;
11823 }
11824 ModuleConfig *new_config = createModuleConfig(config_name, applyfn, privdata, module);
11825 sdsfree(config_name);
11826 new_config->get_fn.get_numeric = getfn;
11827 new_config->set_fn.set_numeric = setfn;
11828 listAddNodeTail(module->module_configs, new_config);
11829 unsigned int numeric_flags = maskModuleNumericConfigFlags(flags);
11830 flags = maskModuleConfigFlags(flags);
11831 addModuleNumericConfig(module->name, name, flags, new_config, default_val, numeric_flags, min, max);
11832 return REDISMODULE_OK;
11833}
11834
11835/* Applies all pending configurations on the module load. This should be called
11836 * after all of the configurations have been registered for the module inside of RedisModule_OnLoad.
11837 * This API needs to be called when configurations are provided in either `MODULE LOADEX`
11838 * or provided as startup arguments. */
11839int RM_LoadConfigs(RedisModuleCtx *ctx) {
11840 if (!ctx || !ctx->module) {
11841 return REDISMODULE_ERR;
11842 }
11843 RedisModule *module = ctx->module;
11844 /* Load configs from conf file or arguments from loadex */
11845 if (loadModuleConfigs(module)) return REDISMODULE_ERR;
11846 return REDISMODULE_OK;
11847}
11848
11849/* Redis MODULE command.
11850 *
11851 * MODULE LIST
11852 * MODULE LOAD <path> [args...]
11853 * MODULE LOADEX <path> [[CONFIG NAME VALUE] [CONFIG NAME VALUE]] [ARGS ...]
11854 * MODULE UNLOAD <name>
11855 */
11856void moduleCommand(client *c) {
11857 char *subcmd = c->argv[1]->ptr;
11858
11859 if (c->argc == 2 && !strcasecmp(subcmd,"help")) {
11860 const char *help[] = {
11861"LIST",
11862" Return a list of loaded modules.",
11863"LOAD <path> [<arg> ...]",
11864" Load a module library from <path>, passing to it any optional arguments.",
11865"LOADEX <path> [[CONFIG NAME VALUE] [CONFIG NAME VALUE]] [ARGS ...]",
11866" Load a module library from <path>, while passing it module configurations and optional arguments.",
11867"UNLOAD <name>",
11868" Unload a module.",
11869NULL
11870 };
11871 addReplyHelp(c, help);
11872 } else if (!strcasecmp(subcmd,"load") && c->argc >= 3) {
11873 robj **argv = NULL;
11874 int argc = 0;
11875
11876 if (c->argc > 3) {
11877 argc = c->argc - 3;
11878 argv = &c->argv[3];
11879 }
11880
11881 if (moduleLoad(c->argv[2]->ptr,(void **)argv,argc, 0) == C_OK)
11882 addReply(c,shared.ok);
11883 else
11884 addReplyError(c,
11885 "Error loading the extension. Please check the server logs.");
11886 } else if (!strcasecmp(subcmd,"loadex") && c->argc >= 3) {
11887 robj **argv = NULL;
11888 int argc = 0;
11889
11890 if (c->argc > 3) {
11891 argc = c->argc - 3;
11892 argv = &c->argv[3];
11893 }
11894 /* If this is a loadex command we want to populate server.module_configs_queue with
11895 * sds NAME VALUE pairs. We also want to increment argv to just after ARGS, if supplied. */
11896 if (parseLoadexArguments((RedisModuleString ***) &argv, &argc) == REDISMODULE_OK &&
11897 moduleLoad(c->argv[2]->ptr, (void **)argv, argc, 1) == C_OK)
11898 addReply(c,shared.ok);
11899 else {
11900 dictEmpty(server.module_configs_queue, NULL);
11901 addReplyError(c,
11902 "Error loading the extension. Please check the server logs.");
11903 }
11904
11905 } else if (!strcasecmp(subcmd,"unload") && c->argc == 3) {
11906 if (moduleUnload(c->argv[2]->ptr) == C_OK)
11907 addReply(c,shared.ok);
11908 else {
11909 char *errmsg;
11910 switch(errno) {
11911 case ENOENT:
11912 errmsg = "no such module with that name";
11913 break;
11914 case EBUSY:
11915 errmsg = "the module exports one or more module-side data "
11916 "types, can't unload";
11917 break;
11918 case EPERM:
11919 errmsg = "the module exports APIs used by other modules. "
11920 "Please unload them first and try again";
11921 break;
11922 case EAGAIN:
11923 errmsg = "the module has blocked clients. "
11924 "Please wait them unblocked and try again";
11925 break;
11926 case EINPROGRESS:
11927 errmsg = "the module holds timer that is not fired. "
11928 "Please stop the timer or wait until it fires.";
11929 break;
11930 default:
11931 errmsg = "operation not possible.";
11932 break;
11933 }
11934 addReplyErrorFormat(c,"Error unloading module: %s",errmsg);
11935 }
11936 } else if (!strcasecmp(subcmd,"list") && c->argc == 2) {
11937 addReplyLoadedModules(c);
11938 } else {
11939 addReplySubcommandSyntaxError(c);
11940 return;
11941 }
11942}
11943
11944/* Return the number of registered modules. */
11945size_t moduleCount(void) {
11946 return dictSize(modules);
11947}
11948
11949/* --------------------------------------------------------------------------
11950 * ## Key eviction API
11951 * -------------------------------------------------------------------------- */
11952
11953/* Set the key last access time for LRU based eviction. not relevant if the
11954 * servers's maxmemory policy is LFU based. Value is idle time in milliseconds.
11955 * returns REDISMODULE_OK if the LRU was updated, REDISMODULE_ERR otherwise. */
11956int RM_SetLRU(RedisModuleKey *key, mstime_t lru_idle) {
11957 if (!key->value)
11958 return REDISMODULE_ERR;
11959 if (objectSetLRUOrLFU(key->value, -1, lru_idle, lru_idle>=0 ? LRU_CLOCK() : 0, 1))
11960 return REDISMODULE_OK;
11961 return REDISMODULE_ERR;
11962}
11963
11964/* Gets the key last access time.
11965 * Value is idletime in milliseconds or -1 if the server's eviction policy is
11966 * LFU based.
11967 * returns REDISMODULE_OK if when key is valid. */
11968int RM_GetLRU(RedisModuleKey *key, mstime_t *lru_idle) {
11969 *lru_idle = -1;
11970 if (!key->value)
11971 return REDISMODULE_ERR;
11972 if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU)
11973 return REDISMODULE_OK;
11974 *lru_idle = estimateObjectIdleTime(key->value);
11975 return REDISMODULE_OK;
11976}
11977
11978/* Set the key access frequency. only relevant if the server's maxmemory policy
11979 * is LFU based.
11980 * The frequency is a logarithmic counter that provides an indication of
11981 * the access frequencyonly (must be <= 255).
11982 * returns REDISMODULE_OK if the LFU was updated, REDISMODULE_ERR otherwise. */
11983int RM_SetLFU(RedisModuleKey *key, long long lfu_freq) {
11984 if (!key->value)
11985 return REDISMODULE_ERR;
11986 if (objectSetLRUOrLFU(key->value, lfu_freq, -1, 0, 1))
11987 return REDISMODULE_OK;
11988 return REDISMODULE_ERR;
11989}
11990
11991/* Gets the key access frequency or -1 if the server's eviction policy is not
11992 * LFU based.
11993 * returns REDISMODULE_OK if when key is valid. */
11994int RM_GetLFU(RedisModuleKey *key, long long *lfu_freq) {
11995 *lfu_freq = -1;
11996 if (!key->value)
11997 return REDISMODULE_ERR;
11998 if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU)
11999 *lfu_freq = LFUDecrAndReturn(key->value);
12000 return REDISMODULE_OK;
12001}
12002
12003/* --------------------------------------------------------------------------
12004 * ## Miscellaneous APIs
12005 * -------------------------------------------------------------------------- */
12006
12007/**
12008 * Returns the full ContextFlags mask, using the return value
12009 * the module can check if a certain set of flags are supported
12010 * by the redis server version in use.
12011 * Example:
12012 *
12013 * int supportedFlags = RM_GetContextFlagsAll();
12014 * if (supportedFlags & REDISMODULE_CTX_FLAGS_MULTI) {
12015 * // REDISMODULE_CTX_FLAGS_MULTI is supported
12016 * } else{
12017 * // REDISMODULE_CTX_FLAGS_MULTI is not supported
12018 * }
12019 */
12020int RM_GetContextFlagsAll() {
12021 return _REDISMODULE_CTX_FLAGS_NEXT - 1;
12022}
12023
12024/**
12025 * Returns the full KeyspaceNotification mask, using the return value
12026 * the module can check if a certain set of flags are supported
12027 * by the redis server version in use.
12028 * Example:
12029 *
12030 * int supportedFlags = RM_GetKeyspaceNotificationFlagsAll();
12031 * if (supportedFlags & REDISMODULE_NOTIFY_LOADED) {
12032 * // REDISMODULE_NOTIFY_LOADED is supported
12033 * } else{
12034 * // REDISMODULE_NOTIFY_LOADED is not supported
12035 * }
12036 */
12037int RM_GetKeyspaceNotificationFlagsAll() {
12038 return _REDISMODULE_NOTIFY_NEXT - 1;
12039}
12040
12041/**
12042 * Return the redis version in format of 0x00MMmmpp.
12043 * Example for 6.0.7 the return value will be 0x00060007.
12044 */
12045int RM_GetServerVersion() {
12046 return REDIS_VERSION_NUM;
12047}
12048
12049/**
12050 * Return the current redis-server runtime value of REDISMODULE_TYPE_METHOD_VERSION.
12051 * You can use that when calling RM_CreateDataType to know which fields of
12052 * RedisModuleTypeMethods are gonna be supported and which will be ignored.
12053 */
12054int RM_GetTypeMethodVersion() {
12055 return REDISMODULE_TYPE_METHOD_VERSION;
12056}
12057
12058/* Replace the value assigned to a module type.
12059 *
12060 * The key must be open for writing, have an existing value, and have a moduleType
12061 * that matches the one specified by the caller.
12062 *
12063 * Unlike RM_ModuleTypeSetValue() which will free the old value, this function
12064 * simply swaps the old value with the new value.
12065 *
12066 * The function returns REDISMODULE_OK on success, REDISMODULE_ERR on errors
12067 * such as:
12068 *
12069 * 1. Key is not opened for writing.
12070 * 2. Key is not a module data type key.
12071 * 3. Key is a module datatype other than 'mt'.
12072 *
12073 * If old_value is non-NULL, the old value is returned by reference.
12074 */
12075int RM_ModuleTypeReplaceValue(RedisModuleKey *key, moduleType *mt, void *new_value, void **old_value) {
12076 if (!(key->mode & REDISMODULE_WRITE) || key->iter)
12077 return REDISMODULE_ERR;
12078 if (!key->value || key->value->type != OBJ_MODULE)
12079 return REDISMODULE_ERR;
12080
12081 moduleValue *mv = key->value->ptr;
12082 if (mv->type != mt)
12083 return REDISMODULE_ERR;
12084
12085 if (old_value)
12086 *old_value = mv->value;
12087 mv->value = new_value;
12088
12089 return REDISMODULE_OK;
12090}
12091
12092/* For a specified command, parse its arguments and return an array that
12093 * contains the indexes of all key name arguments. This function is
12094 * essentially a more efficient way to do `COMMAND GETKEYS`.
12095 *
12096 * The out_flags argument is optional, and can be set to NULL.
12097 * When provided it is filled with REDISMODULE_CMD_KEY_ flags in matching
12098 * indexes with the key indexes of the returned array.
12099 *
12100 * A NULL return value indicates the specified command has no keys, or
12101 * an error condition. Error conditions are indicated by setting errno
12102 * as follows:
12103 *
12104 * * ENOENT: Specified command does not exist.
12105 * * EINVAL: Invalid command arity specified.
12106 *
12107 * NOTE: The returned array is not a Redis Module object so it does not
12108 * get automatically freed even when auto-memory is used. The caller
12109 * must explicitly call RM_Free() to free it, same as the out_flags pointer if
12110 * used.
12111 */
12112int *RM_GetCommandKeysWithFlags(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int *num_keys, int **out_flags) {
12113 UNUSED(ctx);
12114 struct redisCommand *cmd;
12115 int *res = NULL;
12116
12117 /* Find command */
12118 if ((cmd = lookupCommand(argv,argc)) == NULL) {
12119 errno = ENOENT;
12120 return NULL;
12121 }
12122
12123 /* Bail out if command has no keys */
12124 if (!doesCommandHaveKeys(cmd)) {
12125 errno = 0;
12126 return NULL;
12127 }
12128
12129 if ((cmd->arity > 0 && cmd->arity != argc) || (argc < -cmd->arity)) {
12130 errno = EINVAL;
12131 return NULL;
12132 }
12133
12134 getKeysResult result = GETKEYS_RESULT_INIT;
12135 getKeysFromCommand(cmd, argv, argc, &result);
12136
12137 *num_keys = result.numkeys;
12138 if (!result.numkeys) {
12139 errno = 0;
12140 getKeysFreeResult(&result);
12141 return NULL;
12142 }
12143
12144 /* The return value here expects an array of key positions */
12145 unsigned long int size = sizeof(int) * result.numkeys;
12146 res = zmalloc(size);
12147 if (out_flags)
12148 *out_flags = zmalloc(size);
12149 for (int i = 0; i < result.numkeys; i++) {
12150 res[i] = result.keys[i].pos;
12151 if (out_flags)
12152 (*out_flags)[i] = moduleConvertKeySpecsFlags(result.keys[i].flags, 0);
12153 }
12154
12155 return res;
12156}
12157
12158/* Identical to RM_GetCommandKeysWithFlags when flags are not needed. */
12159int *RM_GetCommandKeys(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int *num_keys) {
12160 return RM_GetCommandKeysWithFlags(ctx, argv, argc, num_keys, NULL);
12161}
12162
12163/* Return the name of the command currently running */
12164const char *RM_GetCurrentCommandName(RedisModuleCtx *ctx) {
12165 if (!ctx || !ctx->client || !ctx->client->cmd)
12166 return NULL;
12167
12168 return (const char*)ctx->client->cmd->fullname;
12169}
12170
12171/* --------------------------------------------------------------------------
12172 * ## Defrag API
12173 * -------------------------------------------------------------------------- */
12174
12175/* The defrag context, used to manage state during calls to the data type
12176 * defrag callback.
12177 */
12178typedef struct RedisModuleDefragCtx {
12179 long defragged;
12180 long long int endtime;
12181 unsigned long *cursor;
12182 struct redisObject *key; /* Optional name of key processed, NULL when unknown. */
12183 int dbid; /* The dbid of the key being processed, -1 when unknown. */
12184} RedisModuleDefragCtx;
12185
12186/* Register a defrag callback for global data, i.e. anything that the module
12187 * may allocate that is not tied to a specific data type.
12188 */
12189int RM_RegisterDefragFunc(RedisModuleCtx *ctx, RedisModuleDefragFunc cb) {
12190 ctx->module->defrag_cb = cb;
12191 return REDISMODULE_OK;
12192}
12193
12194/* When the data type defrag callback iterates complex structures, this
12195 * function should be called periodically. A zero (false) return
12196 * indicates the callback may continue its work. A non-zero value (true)
12197 * indicates it should stop.
12198 *
12199 * When stopped, the callback may use RM_DefragCursorSet() to store its
12200 * position so it can later use RM_DefragCursorGet() to resume defragging.
12201 *
12202 * When stopped and more work is left to be done, the callback should
12203 * return 1. Otherwise, it should return 0.
12204 *
12205 * NOTE: Modules should consider the frequency in which this function is called,
12206 * so it generally makes sense to do small batches of work in between calls.
12207 */
12208int RM_DefragShouldStop(RedisModuleDefragCtx *ctx) {
12209 return (ctx->endtime != 0 && ctx->endtime < ustime());
12210}
12211
12212/* Store an arbitrary cursor value for future re-use.
12213 *
12214 * This should only be called if RM_DefragShouldStop() has returned a non-zero
12215 * value and the defrag callback is about to exit without fully iterating its
12216 * data type.
12217 *
12218 * This behavior is reserved to cases where late defrag is performed. Late
12219 * defrag is selected for keys that implement the `free_effort` callback and
12220 * return a `free_effort` value that is larger than the defrag
12221 * 'active-defrag-max-scan-fields' configuration directive.
12222 *
12223 * Smaller keys, keys that do not implement `free_effort` or the global
12224 * defrag callback are not called in late-defrag mode. In those cases, a
12225 * call to this function will return REDISMODULE_ERR.
12226 *
12227 * The cursor may be used by the module to represent some progress into the
12228 * module's data type. Modules may also store additional cursor-related
12229 * information locally and use the cursor as a flag that indicates when
12230 * traversal of a new key begins. This is possible because the API makes
12231 * a guarantee that concurrent defragmentation of multiple keys will
12232 * not be performed.
12233 */
12234int RM_DefragCursorSet(RedisModuleDefragCtx *ctx, unsigned long cursor) {
12235 if (!ctx->cursor)
12236 return REDISMODULE_ERR;
12237
12238 *ctx->cursor = cursor;
12239 return REDISMODULE_OK;
12240}
12241
12242/* Fetch a cursor value that has been previously stored using RM_DefragCursorSet().
12243 *
12244 * If not called for a late defrag operation, REDISMODULE_ERR will be returned and
12245 * the cursor should be ignored. See RM_DefragCursorSet() for more details on
12246 * defrag cursors.
12247 */
12248int RM_DefragCursorGet(RedisModuleDefragCtx *ctx, unsigned long *cursor) {
12249 if (!ctx->cursor)
12250 return REDISMODULE_ERR;
12251
12252 *cursor = *ctx->cursor;
12253 return REDISMODULE_OK;
12254}
12255
12256/* Defrag a memory allocation previously allocated by RM_Alloc, RM_Calloc, etc.
12257 * The defragmentation process involves allocating a new memory block and copying
12258 * the contents to it, like realloc().
12259 *
12260 * If defragmentation was not necessary, NULL is returned and the operation has
12261 * no other effect.
12262 *
12263 * If a non-NULL value is returned, the caller should use the new pointer instead
12264 * of the old one and update any reference to the old pointer, which must not
12265 * be used again.
12266 */
12267void *RM_DefragAlloc(RedisModuleDefragCtx *ctx, void *ptr) {
12268 void *newptr = activeDefragAlloc(ptr);
12269 if (newptr)
12270 ctx->defragged++;
12271
12272 return newptr;
12273}
12274
12275/* Defrag a RedisModuleString previously allocated by RM_Alloc, RM_Calloc, etc.
12276 * See RM_DefragAlloc() for more information on how the defragmentation process
12277 * works.
12278 *
12279 * NOTE: It is only possible to defrag strings that have a single reference.
12280 * Typically this means strings retained with RM_RetainString or RM_HoldString
12281 * may not be defragmentable. One exception is command argvs which, if retained
12282 * by the module, will end up with a single reference (because the reference
12283 * on the Redis side is dropped as soon as the command callback returns).
12284 */
12285RedisModuleString *RM_DefragRedisModuleString(RedisModuleDefragCtx *ctx, RedisModuleString *str) {
12286 return activeDefragStringOb(str, &ctx->defragged);
12287}
12288
12289
12290/* Perform a late defrag of a module datatype key.
12291 *
12292 * Returns a zero value (and initializes the cursor) if no more needs to be done,
12293 * or a non-zero value otherwise.
12294 */
12295int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long endtime, long long *defragged, int dbid) {
12296 moduleValue *mv = value->ptr;
12297 moduleType *mt = mv->type;
12298
12299 RedisModuleDefragCtx defrag_ctx = { 0, endtime, cursor, key, dbid};
12300
12301 /* Invoke callback. Note that the callback may be missing if the key has been
12302 * replaced with a different type since our last visit.
12303 */
12304 int ret = 0;
12305 if (mt->defrag)
12306 ret = mt->defrag(&defrag_ctx, key, &mv->value);
12307
12308 *defragged += defrag_ctx.defragged;
12309 if (!ret) {
12310 *cursor = 0; /* No more work to do */
12311 return 0;
12312 }
12313
12314 return 1;
12315}
12316
12317/* Attempt to defrag a module data type value. Depending on complexity,
12318 * the operation may happen immediately or be scheduled for later.
12319 *
12320 * Returns 1 if the operation has been completed or 0 if it needs to
12321 * be scheduled for late defrag.
12322 */
12323int moduleDefragValue(robj *key, robj *value, long *defragged, int dbid) {
12324 moduleValue *mv = value->ptr;
12325 moduleType *mt = mv->type;
12326
12327 /* Try to defrag moduleValue itself regardless of whether or not
12328 * defrag callbacks are provided.
12329 */
12330 moduleValue *newmv = activeDefragAlloc(mv);
12331 if (newmv) {
12332 (*defragged)++;
12333 value->ptr = mv = newmv;
12334 }
12335
12336 if (!mt->defrag)
12337 return 1;
12338
12339 /* Use free_effort to determine complexity of module value, and if
12340 * necessary schedule it for defragLater instead of quick immediate
12341 * defrag.
12342 */
12343 size_t effort = moduleGetFreeEffort(key, value, dbid);
12344 if (!effort)
12345 effort = SIZE_MAX;
12346 if (effort > server.active_defrag_max_scan_fields) {
12347 return 0; /* Defrag later */
12348 }
12349
12350 RedisModuleDefragCtx defrag_ctx = { 0, 0, NULL, key, dbid};
12351 mt->defrag(&defrag_ctx, key, &mv->value);
12352 (*defragged) += defrag_ctx.defragged;
12353 return 1;
12354}
12355
12356/* Call registered module API defrag functions */
12357long moduleDefragGlobals(void) {
12358 dictIterator *di = dictGetIterator(modules);
12359 dictEntry *de;
12360 long defragged = 0;
12361
12362 while ((de = dictNext(di)) != NULL) {
12363 struct RedisModule *module = dictGetVal(de);
12364 if (!module->defrag_cb)
12365 continue;
12366 RedisModuleDefragCtx defrag_ctx = { 0, 0, NULL, NULL, -1};
12367 module->defrag_cb(&defrag_ctx);
12368 defragged += defrag_ctx.defragged;
12369 }
12370 dictReleaseIterator(di);
12371
12372 return defragged;
12373}
12374
12375/* Returns the name of the key currently being processed.
12376 * There is no guarantee that the key name is always available, so this may return NULL.
12377 */
12378const RedisModuleString *RM_GetKeyNameFromDefragCtx(RedisModuleDefragCtx *ctx) {
12379 return ctx->key;
12380}
12381
12382/* Returns the database id of the key currently being processed.
12383 * There is no guarantee that this info is always available, so this may return -1.
12384 */
12385int RM_GetDbIdFromDefragCtx(RedisModuleDefragCtx *ctx) {
12386 return ctx->dbid;
12387}
12388
12389/* Register all the APIs we export. Keep this function at the end of the
12390 * file so that's easy to seek it to add new entries. */
12391void moduleRegisterCoreAPI(void) {
12392 server.moduleapi = dictCreate(&moduleAPIDictType);
12393 server.sharedapi = dictCreate(&moduleAPIDictType);
12394 REGISTER_API(Alloc);
12395 REGISTER_API(TryAlloc);
12396 REGISTER_API(Calloc);
12397 REGISTER_API(Realloc);
12398 REGISTER_API(Free);
12399 REGISTER_API(Strdup);
12400 REGISTER_API(CreateCommand);
12401 REGISTER_API(GetCommand);
12402 REGISTER_API(CreateSubcommand);
12403 REGISTER_API(SetCommandInfo);
12404 REGISTER_API(SetModuleAttribs);
12405 REGISTER_API(IsModuleNameBusy);
12406 REGISTER_API(WrongArity);
12407 REGISTER_API(ReplyWithLongLong);
12408 REGISTER_API(ReplyWithError);
12409 REGISTER_API(ReplyWithSimpleString);
12410 REGISTER_API(ReplyWithArray);
12411 REGISTER_API(ReplyWithMap);
12412 REGISTER_API(ReplyWithSet);
12413 REGISTER_API(ReplyWithAttribute);
12414 REGISTER_API(ReplyWithNullArray);
12415 REGISTER_API(ReplyWithEmptyArray);
12416 REGISTER_API(ReplySetArrayLength);
12417 REGISTER_API(ReplySetMapLength);
12418 REGISTER_API(ReplySetSetLength);
12419 REGISTER_API(ReplySetAttributeLength);
12420 REGISTER_API(ReplyWithString);
12421 REGISTER_API(ReplyWithEmptyString);
12422 REGISTER_API(ReplyWithVerbatimString);
12423 REGISTER_API(ReplyWithVerbatimStringType);
12424 REGISTER_API(ReplyWithStringBuffer);
12425 REGISTER_API(ReplyWithCString);
12426 REGISTER_API(ReplyWithNull);
12427 REGISTER_API(ReplyWithBool);
12428 REGISTER_API(ReplyWithCallReply);
12429 REGISTER_API(ReplyWithDouble);
12430 REGISTER_API(ReplyWithBigNumber);
12431 REGISTER_API(ReplyWithLongDouble);
12432 REGISTER_API(GetSelectedDb);
12433 REGISTER_API(SelectDb);
12434 REGISTER_API(KeyExists);
12435 REGISTER_API(OpenKey);
12436 REGISTER_API(CloseKey);
12437 REGISTER_API(KeyType);
12438 REGISTER_API(ValueLength);
12439 REGISTER_API(ListPush);
12440 REGISTER_API(ListPop);
12441 REGISTER_API(ListGet);
12442 REGISTER_API(ListSet);
12443 REGISTER_API(ListInsert);
12444 REGISTER_API(ListDelete);
12445 REGISTER_API(StringToLongLong);
12446 REGISTER_API(StringToULongLong);
12447 REGISTER_API(StringToDouble);
12448 REGISTER_API(StringToLongDouble);
12449 REGISTER_API(StringToStreamID);
12450 REGISTER_API(Call);
12451 REGISTER_API(CallReplyProto);
12452 REGISTER_API(FreeCallReply);
12453 REGISTER_API(CallReplyInteger);
12454 REGISTER_API(CallReplyDouble);
12455 REGISTER_API(CallReplyBigNumber);
12456 REGISTER_API(CallReplyVerbatim);
12457 REGISTER_API(CallReplyBool);
12458 REGISTER_API(CallReplySetElement);
12459 REGISTER_API(CallReplyMapElement);
12460 REGISTER_API(CallReplyAttributeElement);
12461 REGISTER_API(CallReplyAttribute);
12462 REGISTER_API(CallReplyType);
12463 REGISTER_API(CallReplyLength);
12464 REGISTER_API(CallReplyArrayElement);
12465 REGISTER_API(CallReplyStringPtr);
12466 REGISTER_API(CreateStringFromCallReply);
12467 REGISTER_API(CreateString);
12468 REGISTER_API(CreateStringFromLongLong);
12469 REGISTER_API(CreateStringFromULongLong);
12470 REGISTER_API(CreateStringFromDouble);
12471 REGISTER_API(CreateStringFromLongDouble);
12472 REGISTER_API(CreateStringFromString);
12473 REGISTER_API(CreateStringFromStreamID);
12474 REGISTER_API(CreateStringPrintf);
12475 REGISTER_API(FreeString);
12476 REGISTER_API(StringPtrLen);
12477 REGISTER_API(AutoMemory);
12478 REGISTER_API(Replicate);
12479 REGISTER_API(ReplicateVerbatim);
12480 REGISTER_API(DeleteKey);
12481 REGISTER_API(UnlinkKey);
12482 REGISTER_API(StringSet);
12483 REGISTER_API(StringDMA);
12484 REGISTER_API(StringTruncate);
12485 REGISTER_API(SetExpire);
12486 REGISTER_API(GetExpire);
12487 REGISTER_API(ResetDataset);
12488 REGISTER_API(DbSize);
12489 REGISTER_API(RandomKey);
12490 REGISTER_API(ZsetAdd);
12491 REGISTER_API(ZsetIncrby);
12492 REGISTER_API(ZsetScore);
12493 REGISTER_API(ZsetRem);
12494 REGISTER_API(ZsetRangeStop);
12495 REGISTER_API(ZsetFirstInScoreRange);
12496 REGISTER_API(ZsetLastInScoreRange);
12497 REGISTER_API(ZsetFirstInLexRange);
12498 REGISTER_API(ZsetLastInLexRange);
12499 REGISTER_API(ZsetRangeCurrentElement);
12500 REGISTER_API(ZsetRangeNext);
12501 REGISTER_API(ZsetRangePrev);
12502 REGISTER_API(ZsetRangeEndReached);
12503 REGISTER_API(HashSet);
12504 REGISTER_API(HashGet);
12505 REGISTER_API(StreamAdd);
12506 REGISTER_API(StreamDelete);
12507 REGISTER_API(StreamIteratorStart);
12508 REGISTER_API(StreamIteratorStop);
12509 REGISTER_API(StreamIteratorNextID);
12510 REGISTER_API(StreamIteratorNextField);
12511 REGISTER_API(StreamIteratorDelete);
12512 REGISTER_API(StreamTrimByLength);
12513 REGISTER_API(StreamTrimByID);
12514 REGISTER_API(IsKeysPositionRequest);
12515 REGISTER_API(KeyAtPos);
12516 REGISTER_API(KeyAtPosWithFlags);
12517 REGISTER_API(IsChannelsPositionRequest);
12518 REGISTER_API(ChannelAtPosWithFlags);
12519 REGISTER_API(GetClientId);
12520 REGISTER_API(GetClientUserNameById);
12521 REGISTER_API(GetContextFlags);
12522 REGISTER_API(AvoidReplicaTraffic);
12523 REGISTER_API(PoolAlloc);
12524 REGISTER_API(CreateDataType);
12525 REGISTER_API(ModuleTypeSetValue);
12526 REGISTER_API(ModuleTypeReplaceValue);
12527 REGISTER_API(ModuleTypeGetType);
12528 REGISTER_API(ModuleTypeGetValue);
12529 REGISTER_API(IsIOError);
12530 REGISTER_API(SetModuleOptions);
12531 REGISTER_API(SignalModifiedKey);
12532 REGISTER_API(SaveUnsigned);
12533 REGISTER_API(LoadUnsigned);
12534 REGISTER_API(SaveSigned);
12535 REGISTER_API(LoadSigned);
12536 REGISTER_API(SaveString);
12537 REGISTER_API(SaveStringBuffer);
12538 REGISTER_API(LoadString);
12539 REGISTER_API(LoadStringBuffer);
12540 REGISTER_API(SaveDouble);
12541 REGISTER_API(LoadDouble);
12542 REGISTER_API(SaveFloat);
12543 REGISTER_API(LoadFloat);
12544 REGISTER_API(SaveLongDouble);
12545 REGISTER_API(LoadLongDouble);
12546 REGISTER_API(SaveDataTypeToString);
12547 REGISTER_API(LoadDataTypeFromString);
12548 REGISTER_API(LoadDataTypeFromStringEncver);
12549 REGISTER_API(EmitAOF);
12550 REGISTER_API(Log);
12551 REGISTER_API(LogIOError);
12552 REGISTER_API(_Assert);
12553 REGISTER_API(LatencyAddSample);
12554 REGISTER_API(StringAppendBuffer);
12555 REGISTER_API(TrimStringAllocation);
12556 REGISTER_API(RetainString);
12557 REGISTER_API(HoldString);
12558 REGISTER_API(StringCompare);
12559 REGISTER_API(GetContextFromIO);
12560 REGISTER_API(GetKeyNameFromIO);
12561 REGISTER_API(GetKeyNameFromModuleKey);
12562 REGISTER_API(GetDbIdFromModuleKey);
12563 REGISTER_API(GetDbIdFromIO);
12564 REGISTER_API(GetKeyNameFromOptCtx);
12565 REGISTER_API(GetToKeyNameFromOptCtx);
12566 REGISTER_API(GetDbIdFromOptCtx);
12567 REGISTER_API(GetToDbIdFromOptCtx);
12568 REGISTER_API(GetKeyNameFromDefragCtx);
12569 REGISTER_API(GetDbIdFromDefragCtx);
12570 REGISTER_API(GetKeyNameFromDigest);
12571 REGISTER_API(GetDbIdFromDigest);
12572 REGISTER_API(BlockClient);
12573 REGISTER_API(UnblockClient);
12574 REGISTER_API(IsBlockedReplyRequest);
12575 REGISTER_API(IsBlockedTimeoutRequest);
12576 REGISTER_API(GetBlockedClientPrivateData);
12577 REGISTER_API(AbortBlock);
12578 REGISTER_API(Milliseconds);
12579 REGISTER_API(MonotonicMicroseconds);
12580 REGISTER_API(BlockedClientMeasureTimeStart);
12581 REGISTER_API(BlockedClientMeasureTimeEnd);
12582 REGISTER_API(GetThreadSafeContext);
12583 REGISTER_API(GetDetachedThreadSafeContext);
12584 REGISTER_API(FreeThreadSafeContext);
12585 REGISTER_API(ThreadSafeContextLock);
12586 REGISTER_API(ThreadSafeContextTryLock);
12587 REGISTER_API(ThreadSafeContextUnlock);
12588 REGISTER_API(DigestAddStringBuffer);
12589 REGISTER_API(DigestAddLongLong);
12590 REGISTER_API(DigestEndSequence);
12591 REGISTER_API(NotifyKeyspaceEvent);
12592 REGISTER_API(GetNotifyKeyspaceEvents);
12593 REGISTER_API(SubscribeToKeyspaceEvents);
12594 REGISTER_API(RegisterClusterMessageReceiver);
12595 REGISTER_API(SendClusterMessage);
12596 REGISTER_API(GetClusterNodeInfo);
12597 REGISTER_API(GetClusterNodesList);
12598 REGISTER_API(FreeClusterNodesList);
12599 REGISTER_API(CreateTimer);
12600 REGISTER_API(StopTimer);
12601 REGISTER_API(GetTimerInfo);
12602 REGISTER_API(GetMyClusterID);
12603 REGISTER_API(GetClusterSize);
12604 REGISTER_API(GetRandomBytes);
12605 REGISTER_API(GetRandomHexChars);
12606 REGISTER_API(BlockedClientDisconnected);
12607 REGISTER_API(SetDisconnectCallback);
12608 REGISTER_API(GetBlockedClientHandle);
12609 REGISTER_API(SetClusterFlags);
12610 REGISTER_API(CreateDict);
12611 REGISTER_API(FreeDict);
12612 REGISTER_API(DictSize);
12613 REGISTER_API(DictSetC);
12614 REGISTER_API(DictReplaceC);
12615 REGISTER_API(DictSet);
12616 REGISTER_API(DictReplace);
12617 REGISTER_API(DictGetC);
12618 REGISTER_API(DictGet);
12619 REGISTER_API(DictDelC);
12620 REGISTER_API(DictDel);
12621 REGISTER_API(DictIteratorStartC);
12622 REGISTER_API(DictIteratorStart);
12623 REGISTER_API(DictIteratorStop);
12624 REGISTER_API(DictIteratorReseekC);
12625 REGISTER_API(DictIteratorReseek);
12626 REGISTER_API(DictNextC);
12627 REGISTER_API(DictPrevC);
12628 REGISTER_API(DictNext);
12629 REGISTER_API(DictPrev);
12630 REGISTER_API(DictCompareC);
12631 REGISTER_API(DictCompare);
12632 REGISTER_API(ExportSharedAPI);
12633 REGISTER_API(GetSharedAPI);
12634 REGISTER_API(RegisterCommandFilter);
12635 REGISTER_API(UnregisterCommandFilter);
12636 REGISTER_API(CommandFilterArgsCount);
12637 REGISTER_API(CommandFilterArgGet);
12638 REGISTER_API(CommandFilterArgInsert);
12639 REGISTER_API(CommandFilterArgReplace);
12640 REGISTER_API(CommandFilterArgDelete);
12641 REGISTER_API(Fork);
12642 REGISTER_API(SendChildHeartbeat);
12643 REGISTER_API(ExitFromChild);
12644 REGISTER_API(KillForkChild);
12645 REGISTER_API(RegisterInfoFunc);
12646 REGISTER_API(InfoAddSection);
12647 REGISTER_API(InfoBeginDictField);
12648 REGISTER_API(InfoEndDictField);
12649 REGISTER_API(InfoAddFieldString);
12650 REGISTER_API(InfoAddFieldCString);
12651 REGISTER_API(InfoAddFieldDouble);
12652 REGISTER_API(InfoAddFieldLongLong);
12653 REGISTER_API(InfoAddFieldULongLong);
12654 REGISTER_API(GetServerInfo);
12655 REGISTER_API(FreeServerInfo);
12656 REGISTER_API(ServerInfoGetField);
12657 REGISTER_API(ServerInfoGetFieldC);
12658 REGISTER_API(ServerInfoGetFieldSigned);
12659 REGISTER_API(ServerInfoGetFieldUnsigned);
12660 REGISTER_API(ServerInfoGetFieldDouble);
12661 REGISTER_API(GetClientInfoById);
12662 REGISTER_API(GetClientNameById);
12663 REGISTER_API(SetClientNameById);
12664 REGISTER_API(PublishMessage);
12665 REGISTER_API(PublishMessageShard);
12666 REGISTER_API(SubscribeToServerEvent);
12667 REGISTER_API(SetLRU);
12668 REGISTER_API(GetLRU);
12669 REGISTER_API(SetLFU);
12670 REGISTER_API(GetLFU);
12671 REGISTER_API(BlockClientOnKeys);
12672 REGISTER_API(SignalKeyAsReady);
12673 REGISTER_API(GetBlockedClientReadyKey);
12674 REGISTER_API(GetUsedMemoryRatio);
12675 REGISTER_API(MallocSize);
12676 REGISTER_API(MallocUsableSize);
12677 REGISTER_API(MallocSizeString);
12678 REGISTER_API(MallocSizeDict);
12679 REGISTER_API(ScanCursorCreate);
12680 REGISTER_API(ScanCursorDestroy);
12681 REGISTER_API(ScanCursorRestart);
12682 REGISTER_API(Scan);
12683 REGISTER_API(ScanKey);
12684 REGISTER_API(CreateModuleUser);
12685 REGISTER_API(SetModuleUserACL);
12686 REGISTER_API(GetCurrentUserName);
12687 REGISTER_API(GetModuleUserFromUserName);
12688 REGISTER_API(ACLCheckCommandPermissions);
12689 REGISTER_API(ACLCheckKeyPermissions);
12690 REGISTER_API(ACLCheckChannelPermissions);
12691 REGISTER_API(ACLAddLogEntry);
12692 REGISTER_API(FreeModuleUser);
12693 REGISTER_API(DeauthenticateAndCloseClient);
12694 REGISTER_API(AuthenticateClientWithACLUser);
12695 REGISTER_API(AuthenticateClientWithUser);
12696 REGISTER_API(GetContextFlagsAll);
12697 REGISTER_API(GetKeyspaceNotificationFlagsAll);
12698 REGISTER_API(IsSubEventSupported);
12699 REGISTER_API(GetServerVersion);
12700 REGISTER_API(GetClientCertificate);
12701 REGISTER_API(RedactClientCommandArgument);
12702 REGISTER_API(GetCommandKeys);
12703 REGISTER_API(GetCommandKeysWithFlags);
12704 REGISTER_API(GetCurrentCommandName);
12705 REGISTER_API(GetTypeMethodVersion);
12706 REGISTER_API(RegisterDefragFunc);
12707 REGISTER_API(DefragAlloc);
12708 REGISTER_API(DefragRedisModuleString);
12709 REGISTER_API(DefragShouldStop);
12710 REGISTER_API(DefragCursorSet);
12711 REGISTER_API(DefragCursorGet);
12712 REGISTER_API(EventLoopAdd);
12713 REGISTER_API(EventLoopDel);
12714 REGISTER_API(EventLoopAddOneShot);
12715 REGISTER_API(Yield);
12716 REGISTER_API(RegisterBoolConfig);
12717 REGISTER_API(RegisterNumericConfig);
12718 REGISTER_API(RegisterStringConfig);
12719 REGISTER_API(RegisterEnumConfig);
12720 REGISTER_API(LoadConfigs);
12721}
12722