From dc43f66eacb0e5d5957f05c5974d016e7351b2d2 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 8 Nov 2013 16:26:50 +0100 Subject: [PATCH] Cluster: UPDATE msg data structure and sending function. --- src/cluster.c | 25 +++++++++++++++++++++++-- src/cluster.h | 14 +++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 998f2eca9..ceafc5c3b 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -59,6 +59,7 @@ void clusterSetMaster(clusterNode *n); void clusterHandleSlaveFailover(void); int bitmapTestBit(unsigned char *bitmap, int pos); void clusterDoBeforeSleep(int flags); +void clusterSendUpdate(clusterLink *link, clusterNode *node); /* ----------------------------------------------------------------------------- * Initialization @@ -1181,8 +1182,11 @@ int clusterProcessPacket(clusterLink *link) { if (server.cluster->slots[j]->configEpoch > senderConfigEpoch) { - printf("MASTER or SLAVE have old config\n"); - break; + redisLog(REDIS_WARNING, + "Node %.40s has old slots configuration, sending " + "an UPDATE message about %.40s\n", + sender->name, server.cluster->slots[j]->name); + clusterSendUpdate(sender->link,server.cluster->slots[j]); } } } @@ -1413,6 +1417,9 @@ void clusterBuildMessageHdr(clusterMsg *hdr, int type) { if (type == CLUSTERMSG_TYPE_FAIL) { totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); totlen += sizeof(clusterMsgDataFail); + } else if (type == CLUSTERMSG_TYPE_UPDATE) { + totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); + totlen += sizeof(clusterMsgDataUpdate); } hdr->totlen = htonl(totlen); /* For PING, PONG, and MEET, fixing the totlen field is up to the caller. */ @@ -1562,6 +1569,20 @@ void clusterSendFail(char *nodename) { clusterBroadcastMessage(buf,ntohl(hdr->totlen)); } +/* Send an UPDATE message to the specified link carrying the specified 'node' + * slots configuration. The node name, slots bitmap, and configEpoch info + * are included. */ +void clusterSendUpdate(clusterLink *link, clusterNode *node) { + unsigned char buf[4096]; + clusterMsg *hdr = (clusterMsg*) buf; + + clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_UPDATE); + memcpy(hdr->data.update.nodecfg.nodename,node->name,REDIS_CLUSTER_NAMELEN); + hdr->data.update.nodecfg.configEpoch = htonu64(node->configEpoch); + memcpy(hdr->data.update.nodecfg.slots,node->slots,sizeof(node->slots)); + clusterSendMessage(link,buf,ntohl(hdr->totlen)); +} + /* ----------------------------------------------------------------------------- * CLUSTER Pub/Sub support * diff --git a/src/cluster.h b/src/cluster.h index 9c598be01..658a364bd 100644 --- a/src/cluster.h +++ b/src/cluster.h @@ -112,7 +112,8 @@ typedef struct clusterState { #define CLUSTERMSG_TYPE_FAIL 3 /* Mark node xxx as failing */ #define CLUSTERMSG_TYPE_PUBLISH 4 /* Pub/Sub Publish propagation */ #define CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST 5 /* May I failover? */ -#define CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 6 /* Yes, you can failover. */ +#define CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 6 /* Yes, you have my vote */ +#define CLUSTERMSG_TYPE_UPDATE 7 /* Another node slots configuration */ /* Initially we don't know our "name", but we'll find it once we connect * to the first node, using the getsockname() function. Then we'll use this @@ -137,6 +138,12 @@ typedef struct { unsigned char bulk_data[8]; /* defined as 8 just for alignment concerns. */ } clusterMsgDataPublish; +typedef struct { + uint64_t configEpoch; /* Config epoch of the specified instance. */ + char nodename[REDIS_CLUSTER_NAMELEN]; /* Name of the slots owner. */ + unsigned char slots[REDIS_CLUSTER_SLOTS/8]; /* Slots bitmap. */ +} clusterMsgDataUpdate; + union clusterMsgData { /* PING, MEET and PONG */ struct { @@ -153,6 +160,11 @@ union clusterMsgData { struct { clusterMsgDataPublish msg; } publish; + + /* UPDATE */ + struct { + clusterMsgDataUpdate nodecfg; + } update; }; typedef struct { -- GitLab