| 4689 | } |
| 4690 | |
| 4691 | sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) { |
| 4692 | sentinelRedisInstance **instance = |
| 4693 | zmalloc(sizeof(instance[0])*dictSize(master->slaves)); |
| 4694 | sentinelRedisInstance *selected = NULL; |
| 4695 | int instances = 0; |
| 4696 | dictIterator *di; |
| 4697 | dictEntry *de; |
| 4698 | mstime_t max_master_down_time = 0; |
| 4699 | |
| 4700 | if (master->flags & SRI_S_DOWN) |
| 4701 | max_master_down_time += mstime() - master->s_down_since_time; |
| 4702 | max_master_down_time += master->down_after_period * 10; |
| 4703 | |
| 4704 | di = dictGetIterator(master->slaves); |
| 4705 | while((de = dictNext(di)) != NULL) { |
| 4706 | sentinelRedisInstance *slave = dictGetVal(de); |
| 4707 | mstime_t info_validity_time; |
| 4708 | |
| 4709 | if (slave->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue; |
| 4710 | if (slave->link->disconnected) continue; |
| 4711 | if (mstime() - slave->link->last_avail_time > SENTINEL_PING_PERIOD*5) continue; |
| 4712 | if (slave->slave_priority == 0) continue; |
| 4713 | |
| 4714 | /* If the master is in SDOWN state we get INFO for slaves every second. |
| 4715 | * Otherwise we get it with the usual period so we need to account for |
| 4716 | * a larger delay. */ |
| 4717 | if (master->flags & SRI_S_DOWN) |
| 4718 | info_validity_time = SENTINEL_PING_PERIOD*5; |
| 4719 | else |
| 4720 | info_validity_time = SENTINEL_INFO_PERIOD*3; |
| 4721 | if (mstime() - slave->info_refresh > info_validity_time) continue; |
| 4722 | if (slave->master_link_down_time > max_master_down_time) continue; |
| 4723 | instance[instances++] = slave; |
| 4724 | } |
| 4725 | dictReleaseIterator(di); |
| 4726 | if (instances) { |
| 4727 | qsort(instance,instances,sizeof(sentinelRedisInstance*), |
| 4728 | compareSlavesForPromotion); |
| 4729 | selected = instance[0]; |
| 4730 | } |
| 4731 | zfree(instance); |
| 4732 | return selected; |
| 4733 | } |
| 4734 | |
| 4735 | /* ---------------- Failover state machine implementation ------------------- */ |
| 4736 | void sentinelFailoverWaitStart(sentinelRedisInstance *ri) { |
no test coverage detected