public static int?WaitUntilLeaderIsElectedOrChanged( ZkClient zkClient, string topic, int partition, long timeoutMs, int?oldLeaderOpt = null) { var leaderLock = new ReentrantLock(); var leaderExistsOrChanged = leaderLock.NewCondition(); if (oldLeaderOpt.HasValue == false) { Logger.InfoFormat("Waiting for leader to be elected for partition [{0},{1}]", topic, partition); } else { Logger.InfoFormat("Waiting for leader for partition [{0},{1}] to be changed from old leader {2}", topic, partition, oldLeaderOpt.Value); } leaderLock.Lock(); try { zkClient.SubscribeDataChanges(ZkUtils.GetTopicPartitionLeaderAndIsrPath(topic, partition), new LeaderExistsOrChangedListener(topic, partition, leaderLock, leaderExistsOrChanged, oldLeaderOpt, zkClient)); leaderExistsOrChanged.Await(TimeSpan.FromMilliseconds(timeoutMs)); // check if leader is elected var leader = ZkUtils.GetLeaderForPartition(zkClient, topic, partition); if (leader != null) { if (oldLeaderOpt.HasValue == false) { Logger.InfoFormat("Leader {0} is elected for partition [{1},{2}]", leader, topic, partition); } else { Logger.InfoFormat( "Leader for partition [{0},{1}] is changed from {2} to {3}", topic, partition, oldLeaderOpt.Value, leader); } } else { Logger.ErrorFormat("Timing out after {0} ms since leader is not elected for partition [{1},{2}]", timeoutMs, topic, partition); } return(leader); } finally { leaderLock.Unlock(); } }