diff --git a/src/cluster.c b/src/cluster.c index 0197aa535..63923fed8 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -655,8 +655,7 @@ int clusterProcessPacket(clusterLink *link) { } } - /* Update our info about served slots if this new node is serving - * slots that are not served from our point of view. */ + /* Update our info about served slots. */ if (sender && sender->flags & REDIS_NODE_MASTER) { int newslots, j; @@ -666,6 +665,9 @@ int clusterProcessPacket(clusterLink *link) { if (newslots) { for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) { if (clusterNodeGetSlotBit(sender,j)) { + /* If this slot was not served, or served by a node + * in FAIL state, update the table with the new node + * caliming to serve the slot. */ if (server.cluster->slots[j] == sender) continue; if (server.cluster->slots[j] == NULL || server.cluster->slots[j]->flags & REDIS_NODE_FAIL) @@ -674,6 +676,16 @@ int clusterProcessPacket(clusterLink *link) { clusterAddSlot(sender,j); update_state = update_config = 1; } + } else { + /* If this slot was served by this node, but it is + * no longer claiming it, del it from the table. */ + if (server.cluster->slots[j] == sender) { + /* Set the bit again before calling + * clusterDelSlot() or the assert will fail. */ + clusterNodeSetSlotBit(sender,j); + clusterDelSlot(j); + update_state = update_config = 1; + } } } }