| 3997 | #define CLUSTER_WRITABLE_DELAY 2000 |
| 3998 | |
| 3999 | void clusterUpdateState(void) { |
| 4000 | int j, new_state; |
| 4001 | int reachable_masters = 0; |
| 4002 | static mstime_t among_minority_time; |
| 4003 | static mstime_t first_call_time = 0; |
| 4004 | |
| 4005 | g_pserver->cluster->todo_before_sleep &= ~CLUSTER_TODO_UPDATE_STATE; |
| 4006 | |
| 4007 | /* If this is a master node, wait some time before turning the state |
| 4008 | * into OK, since it is not a good idea to rejoin the cluster as a writable |
| 4009 | * master, after a reboot, without giving the cluster a chance to |
| 4010 | * reconfigure this node. Note that the delay is calculated starting from |
| 4011 | * the first call to this function and not since the server start, in order |
| 4012 | * to don't count the DB loading time. */ |
| 4013 | if (first_call_time == 0) first_call_time = mstime(); |
| 4014 | if (nodeIsMaster(myself) && |
| 4015 | g_pserver->cluster->state == CLUSTER_FAIL && |
| 4016 | mstime() - first_call_time < CLUSTER_WRITABLE_DELAY) return; |
| 4017 | |
| 4018 | /* Start assuming the state is OK. We'll turn it into FAIL if there |
| 4019 | * are the right conditions. */ |
| 4020 | new_state = CLUSTER_OK; |
| 4021 | |
| 4022 | /* Check if all the slots are covered. */ |
| 4023 | if (g_pserver->cluster_require_full_coverage) { |
| 4024 | for (j = 0; j < CLUSTER_SLOTS; j++) { |
| 4025 | if (g_pserver->cluster->slots[j] == NULL || |
| 4026 | g_pserver->cluster->slots[j]->flags & (CLUSTER_NODE_FAIL)) |
| 4027 | { |
| 4028 | new_state = CLUSTER_FAIL; |
| 4029 | break; |
| 4030 | } |
| 4031 | } |
| 4032 | } |
| 4033 | |
| 4034 | /* Compute the cluster size, that is the number of master nodes |
| 4035 | * serving at least a single slot. |
| 4036 | * |
| 4037 | * At the same time count the number of reachable masters having |
| 4038 | * at least one slot. */ |
| 4039 | { |
| 4040 | dictIterator *di; |
| 4041 | dictEntry *de; |
| 4042 | |
| 4043 | g_pserver->cluster->size = 0; |
| 4044 | di = dictGetSafeIterator(g_pserver->cluster->nodes); |
| 4045 | while((de = dictNext(di)) != NULL) { |
| 4046 | clusterNode *node = (clusterNode*)dictGetVal(de); |
| 4047 | |
| 4048 | if (nodeIsMaster(node) && node->numslots) { |
| 4049 | g_pserver->cluster->size++; |
| 4050 | if ((node->flags & (CLUSTER_NODE_FAIL|CLUSTER_NODE_PFAIL)) == 0) |
| 4051 | reachable_masters++; |
| 4052 | } |
| 4053 | } |
| 4054 | dictReleaseIterator(di); |
| 4055 | } |
| 4056 |
no test coverage detected