Scan all the Sentinels attached to this master to check if there * is a leader for the specified epoch. * * To be a leader for a given epoch, we should have the majority of * the Sentinels we know (ever seen since the last SENTINEL RESET) that * reported the same instance as leader for the same epoch. */
| 4444 | * the Sentinels we know (ever seen since the last SENTINEL RESET) that |
| 4445 | * reported the same instance as leader for the same epoch. */ |
| 4446 | char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) { |
| 4447 | dict *counters; |
| 4448 | dictIterator *di; |
| 4449 | dictEntry *de; |
| 4450 | unsigned int voters = 0, voters_quorum; |
| 4451 | char *myvote; |
| 4452 | char *winner = NULL; |
| 4453 | uint64_t leader_epoch; |
| 4454 | uint64_t max_votes = 0; |
| 4455 | |
| 4456 | serverAssert(master->flags & (SRI_O_DOWN|SRI_FAILOVER_IN_PROGRESS)); |
| 4457 | counters = dictCreate(&leaderVotesDictType,NULL); |
| 4458 | |
| 4459 | voters = dictSize(master->sentinels)+1; /* All the other sentinels and me.*/ |
| 4460 | |
| 4461 | /* Count other sentinels votes */ |
| 4462 | di = dictGetIterator(master->sentinels); |
| 4463 | while((de = dictNext(di)) != NULL) { |
| 4464 | sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); |
| 4465 | if (ri->leader != NULL && ri->leader_epoch == sentinel.current_epoch) |
| 4466 | sentinelLeaderIncr(counters,ri->leader); |
| 4467 | } |
| 4468 | dictReleaseIterator(di); |
| 4469 | |
| 4470 | /* Check what's the winner. For the winner to win, it needs two conditions: |
| 4471 | * 1) Absolute majority between voters (50% + 1). |
| 4472 | * 2) And anyway at least master->quorum votes. */ |
| 4473 | di = dictGetIterator(counters); |
| 4474 | while((de = dictNext(di)) != NULL) { |
| 4475 | uint64_t votes = dictGetUnsignedIntegerVal(de); |
| 4476 | |
| 4477 | if (votes > max_votes) { |
| 4478 | max_votes = votes; |
| 4479 | winner = (char*)dictGetKey(de); |
| 4480 | } |
| 4481 | } |
| 4482 | dictReleaseIterator(di); |
| 4483 | |
| 4484 | /* Count this Sentinel vote: |
| 4485 | * if this Sentinel did not voted yet, either vote for the most |
| 4486 | * common voted sentinel, or for itself if no vote exists at all. */ |
| 4487 | if (winner) |
| 4488 | myvote = sentinelVoteLeader(master,epoch,winner,&leader_epoch); |
| 4489 | else |
| 4490 | myvote = sentinelVoteLeader(master,epoch,sentinel.myid,&leader_epoch); |
| 4491 | |
| 4492 | if (myvote && leader_epoch == epoch) { |
| 4493 | uint64_t votes = sentinelLeaderIncr(counters,myvote); |
| 4494 | |
| 4495 | if (votes > max_votes) { |
| 4496 | max_votes = votes; |
| 4497 | winner = myvote; |
| 4498 | } |
| 4499 | } |
| 4500 | |
| 4501 | voters_quorum = voters/2+1; |
| 4502 | if (winner && (max_votes < voters_quorum || max_votes < master->quorum)) |
| 4503 | winner = NULL; |
no test coverage detected