Commit f23e1511 authored by tammam.alsoleman's avatar tammam.alsoleman

Improved Leader Election Implementation - Avoiding Herd Effect with Smart Watching

parent a76b64e4
...@@ -12,13 +12,14 @@ public class LeaderElection implements Watcher { ...@@ -12,13 +12,14 @@ public class LeaderElection implements Watcher {
private String currentZnodeName; private String currentZnodeName;
private ZooKeeper zooKeeper; private ZooKeeper zooKeeper;
private boolean isLeader = false;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException { public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
LeaderElection leaderElection = new LeaderElection(); LeaderElection leaderElection = new LeaderElection();
leaderElection.connectToZookeeper(); leaderElection.connectToZookeeper();
leaderElection.volunteerForLeadership(); leaderElection.volunteerForLeadership();
leaderElection.electLeader(); leaderElection.electLeaderWithSmartWatching();
leaderElection.run(); leaderElection.run();
leaderElection.close(); leaderElection.close();
System.out.println("Successfully Closed"); System.out.println("Successfully Closed");
...@@ -32,18 +33,28 @@ public class LeaderElection implements Watcher { ...@@ -32,18 +33,28 @@ public class LeaderElection implements Watcher {
this.currentZnodeName = znodeFullPath.replace(ELECTION_NAMESPACE + "/", ""); this.currentZnodeName = znodeFullPath.replace(ELECTION_NAMESPACE + "/", "");
} }
public void electLeader() throws InterruptedException, KeeperException { public void electLeaderWithSmartWatching() throws InterruptedException, KeeperException {
List<String> children = zooKeeper.getChildren(ELECTION_NAMESPACE, this); List<String> children = zooKeeper.getChildren(ELECTION_NAMESPACE, false);
Collections.sort(children); Collections.sort(children);
String smallestChild = children.get(0); //the first element
String smallestChild = children.get(0);
if (smallestChild.equals(currentZnodeName)) { if (smallestChild.equals(currentZnodeName)) {
System.out.println("I'm a leader"); isLeader = true;
System.out.println("I'm the LEADER: " + currentZnodeName);
} else { } else {
System.out.println("I'm not a leader" + smallestChild + " is a leader."); isLeader = false;
int currentIndex = children.indexOf(currentZnodeName);
String previousNode = children.get(currentIndex - 1);
System.out.println("I'm a FOLLOWER. Watching previous node: " + previousNode);
watchPreviousNode(previousNode);
} }
}
private void watchPreviousNode(String previousNode) throws KeeperException, InterruptedException {
String previousNodePath = ELECTION_NAMESPACE + "/" + previousNode;
zooKeeper.exists(previousNodePath, this);
} }
private void close() throws InterruptedException { private void close() throws InterruptedException {
...@@ -74,15 +85,14 @@ public class LeaderElection implements Watcher { ...@@ -74,15 +85,14 @@ public class LeaderElection implements Watcher {
} else if (watchedEvent.getState() == Event.KeeperState.Closed) { } else if (watchedEvent.getState() == Event.KeeperState.Closed) {
System.out.println("Closed Successfully"); System.out.println("Closed Successfully");
} }
case NodeChildrenChanged: case NodeDeleted:
System.out.println("Previous node deleted - re-electing leader");
try { try {
electLeader(); electLeaderWithSmartWatching();
System.out.println(ELECTION_NAMESPACE + " NodeChildrenChanged"); } catch (Exception e) {
} catch (InterruptedException e) { e.printStackTrace();
throw new RuntimeException(e);
} catch (KeeperException e) {
throw new RuntimeException(e);
} }
break;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment