mirror of https://github.com/redis/redis.git
				
				
				
			Modules: RM_Replicate() in thread safe contexts.
This commit is contained in:
		
							parent
							
								
									e938bbc543
								
							
						
					
					
						commit
						1bca62c4b7
					
				
							
								
								
									
										30
									
								
								src/module.c
								
								
								
								
							
							
						
						
									
										30
									
								
								src/module.c
								
								
								
								
							| 
						 | 
					@ -1407,6 +1407,20 @@ void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx) {
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Please refer to RedisModule_Call() for more information.
 | 
					 * Please refer to RedisModule_Call() for more information.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * ## Note about calling this function from a thread safe context:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Normally when you call this function from the callback implementing a
 | 
				
			||||||
 | 
					 * module command, or any other callback provided by the Redis Module API,
 | 
				
			||||||
 | 
					 * Redis will accumulate all the calls to this function in the context of
 | 
				
			||||||
 | 
					 * the callback, and will propagate all the commands wrapped in a MULTI/EXEC
 | 
				
			||||||
 | 
					 * transaction. However when calling this function from a threaded safe context
 | 
				
			||||||
 | 
					 * that can live an undefined amount of time, and can be locked/unlocked in
 | 
				
			||||||
 | 
					 * at will, the behavior is different: MULTI/EXEC wrapper is not emitted
 | 
				
			||||||
 | 
					 * and the command specified is inserted in the AOF and replication stream
 | 
				
			||||||
 | 
					 * immediately.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * ## Return value
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * The command returns REDISMODULE_ERR if the format specifiers are invalid
 | 
					 * The command returns REDISMODULE_ERR if the format specifiers are invalid
 | 
				
			||||||
 * or the command name does not belong to a known command. */
 | 
					 * or the command name does not belong to a known command. */
 | 
				
			||||||
int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
 | 
					int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
 | 
				
			||||||
| 
						 | 
					@ -1424,10 +1438,18 @@ int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...)
 | 
				
			||||||
    va_end(ap);
 | 
					    va_end(ap);
 | 
				
			||||||
    if (argv == NULL) return REDISMODULE_ERR;
 | 
					    if (argv == NULL) return REDISMODULE_ERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Replicate! */
 | 
					    /* Replicate! When we are in a threaded context, we want to just insert
 | 
				
			||||||
    moduleReplicateMultiIfNeeded(ctx);
 | 
					     * the replicated command ASAP, since it is not clear when the context
 | 
				
			||||||
    alsoPropagate(cmd,ctx->client->db->id,argv,argc,
 | 
					     * will stop being used, so accumulating stuff does not make much sense,
 | 
				
			||||||
        PROPAGATE_AOF|PROPAGATE_REPL);
 | 
					     * 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);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        moduleReplicateMultiIfNeeded(ctx);
 | 
				
			||||||
 | 
					        alsoPropagate(cmd,ctx->client->db->id,argv,argc,
 | 
				
			||||||
 | 
					            PROPAGATE_AOF|PROPAGATE_REPL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Release the argv. */
 | 
					    /* Release the argv. */
 | 
				
			||||||
    for (j = 0; j < argc; j++) decrRefCount(argv[j]);
 | 
					    for (j = 0; j < argc; j++) decrRefCount(argv[j]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue