diff --git a/src/aof.c b/src/aof.c index 32684eb89..0e3648ff0 100644 --- a/src/aof.c +++ b/src/aof.c @@ -652,10 +652,11 @@ void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int a /* In Redis commands are always executed in the context of a client, so in * order to load the append only file we need to create a fake client. */ -struct client *createFakeClient(void) { +struct client *createAOFClient(void) { struct client *c = zmalloc(sizeof(*c)); selectDb(c,0); + c->id = CLIENT_ID_AOF; /* So modules can identify it's the AOF client. */ c->conn = NULL; c->name = NULL; c->querybuf = sdsempty(); @@ -729,7 +730,7 @@ int loadAppendOnlyFile(char *filename) { * to the same file we're about to read. */ server.aof_state = AOF_OFF; - fakeClient = createFakeClient(); + fakeClient = createAOFClient(); startLoadingFile(fp, filename); /* Check if this AOF file has an RDB preamble. In that case we need to diff --git a/src/module.c b/src/module.c index fe497f5dc..cf6da9aa1 100644 --- a/src/module.c +++ b/src/module.c @@ -1504,7 +1504,15 @@ int RM_ReplicateVerbatim(RedisModuleCtx *ctx) { * are guaranteed to get IDs greater than any past ID previously seen. * * Valid IDs are from 1 to 2^64-1. If 0 is returned it means there is no way - * to fetch the ID in the context the function was currently called. */ + * to fetch the ID in the context the function was currently called. + * + * After obtaining the ID, it is possible to check if the command execution + * is actually happening in the context of AOF loading, using this macro: + * + * if (RedisModule_IsAOFClient(RedisModule_GetClientId(ctx)) { + * // Handle it differently. + * } + */ unsigned long long RM_GetClientId(RedisModuleCtx *ctx) { if (ctx->client == NULL) return 0; return ctx->client->id; diff --git a/src/redismodule.h b/src/redismodule.h index a7e69f7b3..19a9cd897 100644 --- a/src/redismodule.h +++ b/src/redismodule.h @@ -404,6 +404,8 @@ int REDISMODULE_API_FUNC(RedisModule_ExitFromChild)(int retcode); int REDISMODULE_API_FUNC(RedisModule_KillForkChild)(int child_pid); #endif +#define RedisModule_IsAOFClient(id) ((id) == UINT64_MAX) + /* This is included inline inside each Redis module. */ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) __attribute__((unused)); static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int apiver) { diff --git a/src/server.h b/src/server.h index 00b54bd35..829d8213e 100644 --- a/src/server.h +++ b/src/server.h @@ -827,6 +827,11 @@ typedef struct user { /* With multiplexing we need to take per-client state. * Clients are taken in a linked list. */ + +#define CLIENT_ID_AOF (UINT64_MAX) /* Reserved ID for the AOF client. If you + need more reserved IDs use UINT64_MAX-1, + -2, ... and so forth. */ + typedef struct client { uint64_t id; /* Client incremental unique ID. */ connection *conn;