summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2019-10-04 11:44:39 +0200
committerantirez <antirez@gmail.com>2019-10-04 11:44:53 +0200
commit2a81e49ddee1db6ae3c09bc8b9e1b05d430571f0 (patch)
treeaa2fa525e94981b829622cd2d16911afd8d6cb1b
parent1b8b8c029fa09511bfeb01c1808456de7a28565d (diff)
downloadredis-2a81e49ddee1db6ae3c09bc8b9e1b05d430571f0.tar.gz
Modules: RM_Call/Replicate() ability to exclude AOF/replicas.
-rw-r--r--src/module.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/module.c b/src/module.c
index c87f81c5d..0e9c22e54 100644
--- a/src/module.c
+++ b/src/module.c
@@ -318,6 +318,10 @@ static struct RedisModuleForkInfo {
void* done_handler_user_data;
} moduleForkInfo = {0};
+/* Flags for moduleCreateArgvFromUserFormat(). */
+#define REDISMODULE_ARGV_REPLICATE (1<<0)
+#define REDISMODULE_ARGV_NO_AOF (1<<1)
+#define REDISMODULE_ARGV_NO_REPLICAS (1<<2)
/* --------------------------------------------------------------------------
* Prototypes
@@ -1407,6 +1411,10 @@ void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx) {
*
* Please refer to RedisModule_Call() for more information.
*
+ * Using the special "A" and "R" modifiers, the caller can exclude either
+ * the AOF or the replicas from the propagation of the specified command.
+ * Otherwise, by default, the command will be propagated in both channels.
+ *
* ## Note about calling this function from a thread safe context:
*
* Normally when you call this function from the callback implementing a
@@ -1438,17 +1446,22 @@ int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...)
va_end(ap);
if (argv == NULL) return REDISMODULE_ERR;
+ /* Select the propagation target. Usually is AOF + replicas, however
+ * the caller can exclude one or the other using the "A" or "R"
+ * modifiers. */
+ int target = 0;
+ if (!(flags & REDISMODULE_ARGV_NO_AOF)) target |= PROPAGATE_AOF;
+ if (!(flags & REDISMODULE_ARGV_NO_REPLICAS)) target |= PROPAGATE_REPL;
+
/* Replicate! When we are in a threaded context, we want to just insert
* the replicated command ASAP, since it is not clear when the context
* will stop being used, so accumulating stuff does not make much sense,
* nor we could easily use the alsoPropagate() API from threads. */
if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) {
- propagate(cmd,ctx->client->db->id,argv,argc,
- PROPAGATE_AOF|PROPAGATE_REPL);
+ propagate(cmd,ctx->client->db->id,argv,argc,target);
} else {
moduleReplicateMultiIfNeeded(ctx);
- alsoPropagate(cmd,ctx->client->db->id,argv,argc,
- PROPAGATE_AOF|PROPAGATE_REPL);
+ alsoPropagate(cmd,ctx->client->db->id,argv,argc,target);
}
/* Release the argv. */
@@ -2767,12 +2780,11 @@ RedisModuleString *RM_CreateStringFromCallReply(RedisModuleCallReply *reply) {
* to special modifiers in "fmt". For now only one exists:
*
* "!" -> REDISMODULE_ARGV_REPLICATE
+ * "A" -> REDISMODULE_ARGV_NO_AOF
+ * "R" -> REDISMODULE_ARGV_NO_REPLICAS
*
* On error (format specifier error) NULL is returned and nothing is
* allocated. On success the argument vector is returned. */
-
-#define REDISMODULE_ARGV_REPLICATE (1<<0)
-
robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *flags, va_list ap) {
int argc = 0, argv_size, j;
robj **argv = NULL;
@@ -2821,6 +2833,10 @@ robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int
}
} else if (*p == '!') {
if (flags) (*flags) |= REDISMODULE_ARGV_REPLICATE;
+ } else if (*p == 'A') {
+ if (flags) (*flags) |= REDISMODULE_ARGV_NO_AOF;
+ } else if (*p == 'R') {
+ if (flags) (*flags) |= REDISMODULE_ARGV_NO_REPLICAS;
} else {
goto fmterr;
}
@@ -2912,8 +2928,10 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
/* Run the command */
int call_flags = CMD_CALL_SLOWLOG | CMD_CALL_STATS;
if (replicate) {
- call_flags |= CMD_CALL_PROPAGATE_AOF;
- call_flags |= CMD_CALL_PROPAGATE_REPL;
+ if (!(flags & REDISMODULE_ARGV_NO_AOF))
+ call_flags |= CMD_CALL_PROPAGATE_AOF;
+ if (!(flags & REDISMODULE_ARGV_NO_REPLICAS))
+ call_flags |= CMD_CALL_PROPAGATE_REPL;
}
call(c,call_flags);