MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / sentinelGetLeader

Function sentinelGetLeader

src/sentinel.cpp:4446–4509  ·  view source on GitHub ↗

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. */

Source from the content-addressed store, hash-verified

4444 * the Sentinels we know (ever seen since the last SENTINEL RESET) that
4445 * reported the same instance as leader for the same epoch. */
4446char *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;

Callers 1

Calls 9

sentinelLeaderIncrFunction · 0.85
sentinelVoteLeaderFunction · 0.85
sdsnewFunction · 0.85
sdsfreeFunction · 0.85
dictCreateFunction · 0.70
dictGetIteratorFunction · 0.70
dictNextFunction · 0.70
dictReleaseIteratorFunction · 0.70
dictReleaseFunction · 0.70

Tested by

no test coverage detected