apache-zookeeperapache-curatorleader

Apache Curator LeaderSelector: How to avoid giving up leadership by not exiting from takeLeadership() method?


I'm trying to implement a simple leader election based system where my main business logic of the application runs on the elected leader node. As part of acquiring leadership, the main business logic starts various other services. I'm using Apache Curator LeaderSelector recipe to implement the leader selection process.

In my system, the node which gets selected as the leader keeps the leadership until failure forces another leader to be selected. In other words, once I get the leadership I don't want to relinquish it.

According to Curator LeaderSelection documentation, leadership gets relinquished when the takeLeadership() method returns. I want to avoid it, and I'm right now just block the return by introducing a wait loop.

My question is:

  1. Is this the right way to implement leadership?
  2. Is the wait loop (as shown in the code example below) the right way to block?

    public class MainBusinessLogic extends LeaderSelectorListenerAdapter {      
      private static final String ZK_PATH_LEADER_ROOT = "/some-path";
      private final CuratorFramework client;
      private final LeaderSelector leaderSelector;
    
      public MainBusinessLogic() {
        client = CuratorService.getInstance().getCuratorFramework();
        leaderSelector = new LeaderSelector(client, ZK_PATH_LEADER_ROOT, this);
        leaderSelector.autoRequeue();
        leaderSelector.start();
      }
    
      @Override
      public void takeLeadership(CuratorFramework client) throws IOException {
        // Start various other internal services...
        ServiceA serviceA = new ServiceA(...);
        ServiceB serviceB = new ServiceB(...);
        ...
        ...
        serviceA.start();
        serviceB.start();
        ...
        ...
    
        // We are done but need to keep leadership to this instance, else all the business
        // logic and services will start on another node.
        // Is this the right way to prevent relinquishing leadership???
        while (true) {
          synchronized (this) {
            try {
              wait();
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      }
    }
    

Solution

  • LeaderLatchInstead of the wait(), you can just do:

    Thread.currentThread().join();
    

    But, yes, that's correct.

    BTW - if you prefer a different method, you can use LeaderLatch with a LeaderLatchListener.