diff --git a/src/module.c b/src/module.c index 62de1308..a38540bb 100644 --- a/src/module.c +++ b/src/module.c @@ -3983,7 +3983,9 @@ void RM_FreeClusterNodesList(char **ids) { clusterNode *clusterLookupNode(const char *name); /* We need access to internals */ -int RM_GetClusterNodeInfo(const char *id, char *ip, char *master_id, int *port, int *flags) { +int RM_GetClusterNodeInfo(RedisModuleCtx *ctx, const char *id, char *ip, char *master_id, int *port, int *flags) { + UNUSED(ctx); + clusterNode *node = clusterLookupNode(id); if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) return REDISMODULE_ERR; @@ -4396,4 +4398,7 @@ void moduleRegisterCoreAPI(void) { REGISTER_API(SubscribeToKeyspaceEvents); REGISTER_API(RegisterClusterMessageReceiver); REGISTER_API(SendClusterMessage); + REGISTER_API(GetClusterNodeInfo); + REGISTER_API(GetClusterNodesList); + REGISTER_API(FreeClusterNodesList); } diff --git a/src/modules/hellocluster.c b/src/modules/hellocluster.c index db042d92..4cc40a17 100644 --- a/src/modules/hellocluster.c +++ b/src/modules/hellocluster.c @@ -39,6 +39,7 @@ #define MSGTYPE_PING 1 #define MSGTYPE_PONG 2 +/* HELLOCLUSTER.PINGALL */ int PingallCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { REDISMODULE_NOT_USED(argv); REDISMODULE_NOT_USED(argc); @@ -47,15 +48,38 @@ int PingallCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, i return RedisModule_ReplyWithSimpleString(ctx, "OK"); } +/* HELLOCLUSTER.LIST */ +int ListCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + REDISMODULE_NOT_USED(argv); + REDISMODULE_NOT_USED(argc); + + size_t numnodes; + char **ids = RedisModule_GetClusterNodesList(ctx,&numnodes); + if (ids == NULL) { + return RedisModule_ReplyWithError(ctx,"Cluster not enabled"); + } + + RedisModule_ReplyWithArray(ctx,numnodes); + for (size_t j = 0; j < numnodes; j++) { + int port; + RedisModule_GetClusterNodeInfo(ctx,ids[j],NULL,NULL,&port,NULL); + RedisModule_ReplyWithArray(ctx,2); + RedisModule_ReplyWithStringBuffer(ctx,ids[j],REDISMODULE_NODE_ID_LEN); + RedisModule_ReplyWithLongLong(ctx,port); + } + RedisModule_FreeClusterNodesList(ids); + return RedisModule_ReplyWithSimpleString(ctx, "OK"); +} + /* Callback for message MSGTYPE_PING */ -void PingReceiver(RedisModuleCtx *ctx, char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) { +void PingReceiver(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) { RedisModule_Log(ctx,"notice","PING (type %d) RECEIVED from %.*s: '%.*s'", type,REDISMODULE_NODE_ID_LEN,sender_id,(int)len, payload); RedisModule_SendClusterMessage(ctx,NULL,MSGTYPE_PONG,(unsigned char*)"Ohi!",4); } /* Callback for message MSGTYPE_PONG. */ -void PongReceiver(RedisModuleCtx *ctx, char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) { +void PongReceiver(RedisModuleCtx *ctx, const char *sender_id, uint8_t type, const unsigned char *payload, uint32_t len) { RedisModule_Log(ctx,"notice","PONG (type %d) RECEIVED from %.*s: '%.*s'", type,REDISMODULE_NODE_ID_LEN,sender_id,(int)len, payload); } @@ -73,6 +97,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) PingallCommand_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR) return REDISMODULE_ERR; + if (RedisModule_CreateCommand(ctx,"hellocluster.list", + ListCommand_RedisCommand,"readonly",0,0,0) == REDISMODULE_ERR) + return REDISMODULE_ERR; + RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PING,PingReceiver); RedisModule_RegisterClusterMessageReceiver(ctx,MSGTYPE_PONG,PongReceiver); return REDISMODULE_OK; diff --git a/src/redismodule.h b/src/redismodule.h index 83048b83..345cd5e1 100644 --- a/src/redismodule.h +++ b/src/redismodule.h @@ -263,6 +263,9 @@ void REDISMODULE_API_FUNC(RedisModule_DigestAddLongLong)(RedisModuleDigest *md, void REDISMODULE_API_FUNC(RedisModule_DigestEndSequence)(RedisModuleDigest *md); void REDISMODULE_API_FUNC(RedisModule_RegisterClusterMessageReceiver)(RedisModuleCtx *ctx, uint8_t type, RedisModuleClusterMessageReceiver callback); int REDISMODULE_API_FUNC(RedisModule_SendClusterMessage)(RedisModuleCtx *ctx, char *target_id, uint8_t type, unsigned char *msg, uint32_t len); +int REDISMODULE_API_FUNC(RedisModule_GetClusterNodeInfo)(RedisModuleCtx *ctx, const char *id, char *ip, char *master_id, int *port, int *flags); +char **REDISMODULE_API_FUNC(RedisModule_GetClusterNodesList)(RedisModuleCtx *ctx, size_t *numnodes); +void REDISMODULE_API_FUNC(RedisModule_FreeClusterNodesList)(char **ids); /* Experimental APIs */ #ifdef REDISMODULE_EXPERIMENTAL_API @@ -388,6 +391,9 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int REDISMODULE_GET_API(DigestEndSequence); REDISMODULE_GET_API(RegisterClusterMessageReceiver); REDISMODULE_GET_API(SendClusterMessage); + REDISMODULE_GET_API(GetClusterNodeInfo); + REDISMODULE_GET_API(GetClusterNodesList); + REDISMODULE_GET_API(FreeClusterNodesList); #ifdef REDISMODULE_EXPERIMENTAL_API REDISMODULE_GET_API(GetThreadSafeContext);