From d34c2fa3bb79f9bbbaaafc6d0e74973e5a3b963a Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 7 Jun 2014 17:27:49 +0200 Subject: [PATCH] ROLE command added. The new ROLE command is designed in order to provide a client with informations about the replication in a fast and easy to use way compared to the INFO command where the same information is also available. --- src/redis.c | 1 + src/redis.h | 1 + src/replication.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/redis.c b/src/redis.c index dc9f4c95..89eaf436 100644 --- a/src/redis.c +++ b/src/redis.c @@ -243,6 +243,7 @@ struct redisCommand redisCommandTable[] = { {"pttl",pttlCommand,2,"r",0,NULL,1,1,1,0,0}, {"persist",persistCommand,2,"w",0,NULL,1,1,1,0,0}, {"slaveof",slaveofCommand,3,"ast",0,NULL,0,0,0,0,0}, + {"role",roleCommand,1,"ast",0,NULL,0,0,0,0,0}, {"debug",debugCommand,-2,"as",0,NULL,0,0,0,0,0}, {"config",configCommand,-2,"art",0,NULL,0,0,0,0,0}, {"subscribe",subscribeCommand,-2,"rpslt",0,NULL,0,0,0,0,0}, diff --git a/src/redis.h b/src/redis.h index cdf7cb5c..7c55f902 100644 --- a/src/redis.h +++ b/src/redis.h @@ -1394,6 +1394,7 @@ void ttlCommand(redisClient *c); void pttlCommand(redisClient *c); void persistCommand(redisClient *c); void slaveofCommand(redisClient *c); +void roleCommand(redisClient *c); void debugCommand(redisClient *c); void msetCommand(redisClient *c); void msetnxCommand(redisClient *c); diff --git a/src/replication.c b/src/replication.c index 94aacea5..5f4c2d38 100644 --- a/src/replication.c +++ b/src/replication.c @@ -1324,6 +1324,43 @@ void slaveofCommand(redisClient *c) { addReply(c,shared.ok); } +/* ROLE command: provide information about the role of the instance + * (master or slave) and additional information related to replication + * in an easy to process format. */ +void roleCommand(redisClient *c) { + if (server.masterhost == NULL) { + listIter li; + listNode *ln; + void *mbcount; + int slaves = 0; + + addReplyMultiBulkLen(c,3); + addReplyBulkCBuffer(c,"master",6); + addReplyLongLong(c,server.master_repl_offset); + mbcount = addDeferredMultiBulkLength(c); + listRewind(server.slaves,&li); + while((ln = listNext(&li))) { + redisClient *slave = ln->value; + char ip[REDIS_IP_STR_LEN]; + + if (anetPeerToString(slave->fd,ip,sizeof(ip),NULL) == -1) continue; + if (slave->replstate != REDIS_REPL_ONLINE) continue; + addReplyMultiBulkLen(c,3); + addReplyBulkCString(c,ip); + addReplyBulkLongLong(c,slave->slave_listening_port); + addReplyBulkLongLong(c,slave->repl_ack_off); + slaves++; + } + setDeferredMultiBulkLength(c,mbcount,slaves); + } else { + addReplyMultiBulkLen(c,4); + addReplyBulkCBuffer(c,"slave",5); + addReplyBulkCString(c,server.masterhost); + addReplyLongLong(c,server.masterport); + addReplyLongLong(c,server.master->reploff); + } +} + /* Send a REPLCONF ACK command to the master to inform it about the current * processed offset. If we are not connected with a master, the command has * no effects. */