Return-Path: X-Original-To: apmail-curator-user-archive@minotaur.apache.org Delivered-To: apmail-curator-user-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8C4FCC706 for ; Fri, 16 Jan 2015 04:07:24 +0000 (UTC) Received: (qmail 25118 invoked by uid 500); 16 Jan 2015 04:07:26 -0000 Delivered-To: apmail-curator-user-archive@curator.apache.org Received: (qmail 25064 invoked by uid 500); 16 Jan 2015 04:07:25 -0000 Mailing-List: contact user-help@curator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@curator.apache.org Delivered-To: mailing list user@curator.apache.org Received: (qmail 25054 invoked by uid 99); 16 Jan 2015 04:07:25 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 16 Jan 2015 04:07:25 +0000 X-ASF-Spam-Status: No, hits=2.5 required=5.0 tests=FREEMAIL_REPLY,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of mckenzie.cam@gmail.com designates 209.85.217.177 as permitted sender) Received: from [209.85.217.177] (HELO mail-lb0-f177.google.com) (209.85.217.177) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 16 Jan 2015 04:06:59 +0000 Received: by mail-lb0-f177.google.com with SMTP id b6so16586609lbj.8 for ; Thu, 15 Jan 2015 20:06:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=EWeOA/OH5Zw9i6RtsjjYZNfCAyvdjnfSv/pn+PQIFUc=; b=CWhXyMfIFMwdX4GXDkZDv26sAxhrEriZf4UrBQblKckXyNt2+6eBsi7AdqW9opCl4C nu8WLalswiW4/oXAxe93QgE4kKeCG58kRXKjSD21Y9fp9slGho50+/PRyGQdjW1wpOYt WyFCJ/xfdeX/c6bj7WJ/ij49iP8rfxT4J5CqcYWYiY5jaswiZ8lynlqq+EzqU67Ic8OZ /b+od7+BQ1EpL/X7h2/hrOk6lStnUFfNheCV4TFBDr6/iKgj6kwGfHG8zwbEAENNZoJ0 zqUXKkXmey6i16VznuS6lJOlZ5P78Ncio+hOprtLBZ1TgUdg9brjH+bPuCJ67iGT1mHb TrdQ== MIME-Version: 1.0 X-Received: by 10.153.11.170 with SMTP id ej10mr13458913lad.24.1421381173596; Thu, 15 Jan 2015 20:06:13 -0800 (PST) Received: by 10.112.19.99 with HTTP; Thu, 15 Jan 2015 20:06:13 -0800 (PST) In-Reply-To: References: Date: Fri, 16 Jan 2015 15:06:13 +1100 Message-ID: Subject: Re: Zookeeper Leadership election with curator From: Cameron McKenzie To: user@curator.apache.org Cc: Jordan Zimmerman Content-Type: multipart/alternative; boundary=001a11347914f156dc050cbd1741 X-Virus-Checked: Checked by ClamAV on apache.org --001a11347914f156dc050cbd1741 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable The InterProcessMutex is essentially a distributed lock. In each of your clients you just create an InterProcessMutex instance referring to the same ZK path CuratorFramework curator =3D ... String lockPath =3D "/lockPath"; InterProcessMutex mutex =3D new InterProcessMutex(curator, lockPath); try { //This will block until the mutex is acquire. mutex.acquire(); //Do your critical stuff } finally { //Release the mutex mutex.release(); } On Fri, Jan 16, 2015 at 12:05 PM, Check Peck wrote: > What is the benefit I will have with InterProcessMutex? I have never use > this before. Is there any example which I can take a look? > > On Thu, Jan 15, 2015 at 4:07 PM, Cameron McKenzie > wrote: > >> Yes, good point. >> >> On Fri, Jan 16, 2015 at 10:57 AM, Jordan Zimmerman < >> jordan@jordanzimmerman.com> wrote: >> >>> But if you go through that much trouble you might as well just use >>> InterProcessMutex. >>> >>> -JZ >>> >>> >>> >>> On January 15, 2015 at 6:54:30 PM, Cameron McKenzie ( >>> mckenzie.cam@gmail.com) wrote: >>> >>> If you use the callback as Jordan suggested, then you can just block >>> on a latch, and then get this latch to be updated by the callback when = it >>> is notified that it's leader. Then you won't have to wait for some fixe= d >>> amount of time, it will just block until it's leader. >>> >>> >>> On Fri, Jan 16, 2015 at 10:48 AM, Check Peck >>> wrote: >>> >>>> As of now, I am adding a sleep of 1 minute and it works fine before I >>>> check whether I am a leader or not. >>>> >>>> On Thu, Jan 15, 2015 at 3:43 PM, Check Peck >>>> wrote: >>>> >>>>> Yes that makes sense that 1 client will be leader. But suppose I >>>>> have 5 background threads running in 5 different machines and each >>>>> background thread is in different classes and I want to make sure tha= t >>>>> those 5 background threads are running from a single machine who is t= he >>>>> leader so that's why we are doing that check whether I am the leader = then >>>>> do this. >>>>> >>>>> Will this work if we add a Listener to leaderlatch? >>>>> >>>>> On Thu, Jan 15, 2015 at 3:30 PM, Jordan Zimmerman < >>>>> jordan@jordanzimmerman.com> wrote: >>>>> >>>>>> The problem with that is you have to wait until you are the leader. >>>>>> The benefit of LeaderSelector is that it has a callback that is invo= ked >>>>>> when you are the leader. Remember, you are in a multithreaded, multi= client >>>>>> environment. Only 1 client is going to be the leader. Maybe what you= are >>>>>> after is an InterProcessMutex? >>>>>> >>>>>> -JZ >>>>>> >>>>>> >>>>>> >>>>>> On January 15, 2015 at 6:24:06 PM, Check Peck ( >>>>>> comptechgeeky@gmail.com) wrote: >>>>>> >>>>>> I saw the leader election code here - >>>>>> https://git-wip-us.apache.org/repos/asf?p=3Dcurator.git;a=3Dtree;f= =3Dcurator-examples/src/main/java/leader;h=3D73b547eadb98995c0ccbd06a5b76d0= 741ffef263;hb=3DHEAD >>>>>> >>>>>> But didn't understand few things - How can I call something like thi= s >>>>>> in my code - I want to do stuff in my code by just checking whether= I am >>>>>> the leader or not. And from the LeaderSelectorExample, I am not able= to >>>>>> understand this. >>>>>> >>>>>> if (zookClient.isLeader()) { >>>>>> >>>>>> // then do stuff >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> On Thu, Jan 15, 2015 at 3:17 PM, Jordan Zimmerman < >>>>>> jordan@jordanzimmerman.com> wrote: >>>>>> >>>>>>> Oh - maybe I read the code too fast. I guess it doesn=E2=80=99t ma= ke more >>>>>>> than one=E2=80=A6 >>>>>>> >>>>>>> There=E2=80=99s an example of LeaderSelector here: >>>>>>> http://curator.apache.org/curator-examples/index.html >>>>>>> >>>>>>> >>>>>>> On January 15, 2015 at 6:00:03 PM, Check Peck ( >>>>>>> comptechgeeky@gmail.com) wrote: >>>>>>> >>>>>>> Thanks Jordan for the input. >>>>>>> >>>>>>> * Where do you see that I am creating new Curator instance for each >>>>>>> Leader? I guess I am using one Curator instance for my application? >>>>>>> * Ok, I have commented out this line in ZookeeperClient class >>>>>>> * That's a good point, how would I use the listener or the >>>>>>> leaderselector in my code base? If possible, can you provide an exa= mple? >>>>>>> >>>>>>> >>>>>>> On Thu, Jan 15, 2015 at 2:38 PM, Jordan Zimmerman < >>>>>>> jordan@jordanzimmerman.com> wrote: >>>>>>> >>>>>>>> A few things: >>>>>>>> >>>>>>>> * You don=E2=80=99t need to create a new Curator instance for eac= h Leader. >>>>>>>> One Curator instance can be used for an application. >>>>>>>> * Calling >>>>>>>> client.getZookeeperClient().blockUntilConnectedOrTimedOut(); is un= necessary >>>>>>>> * Calling isLeader() immediately after starting the latch may not >>>>>>>> work. It takes time for the leader to get selected. LeaderLatch ha= s a >>>>>>>> listener if you want to get notified. Alternatively, you can use >>>>>>>> LeaderSelector. >>>>>>>> >>>>>>>> Hope this helps. >>>>>>>> >>>>>>>> -Jordan >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On January 15, 2015 at 5:25:26 PM, Check Peck ( >>>>>>>> comptechgeeky@gmail.com) wrote: >>>>>>>> >>>>>>>> I am using Zookeeper for the leadership election process. I have >>>>>>>> three nodes zookeeper ensemble. >>>>>>>> >>>>>>>> We have a node like this "/test/msn" on which we are doing the >>>>>>>> leadership election and it works fine and we have application serv= ers >>>>>>>> running it in production and using "/test/msn" node for leadership= . And >>>>>>>> this program is always running. >>>>>>>> >>>>>>>> Now we created another node like this "/testpnl" in the same >>>>>>>> zookeeper servers. And we have another set of machines which is tr= ying to >>>>>>>> do the leadership election on that node and whenever I run my prog= ram in >>>>>>>> production from one servers, it always returns back that the node = is not >>>>>>>> leader? And I can see only one node inside "/testpnl" and it is th= e same >>>>>>>> node from which I am running my program? >>>>>>>> >>>>>>>> I am using Curator 2.7.0 and the zookeeper version is 3.4.5 Is >>>>>>>> there anything wrong with my setup or zookeeper has some bug which= I am not >>>>>>>> aware? >>>>>>>> >>>>>>>> Is anything >>>>>>>> >>>>>>>> public class ZookeeperLeaderTester { >>>>>>>> >>>>>>>> private ZookeeperClient zookClient; >>>>>>>> >>>>>>>> private static final String ZOOK_PRODUCTION =3D >>>>>>>> "host1:2181,host2:2181,host3:2181"; >>>>>>>> private static final String LEADERSHIP_NODE =3D "/testpnl"= ; >>>>>>>> >>>>>>>> private static class Holder { >>>>>>>> static final ZookeeperLeaderTester INSTANCE =3D new >>>>>>>> ZookeeperLeaderTester(); >>>>>>>> } >>>>>>>> >>>>>>>> public static ZookeeperLeaderTester getInstance() { >>>>>>>> return Holder.INSTANCE; >>>>>>>> } >>>>>>>> >>>>>>>> private ZookeeperLeaderTester() { >>>>>>>> try { >>>>>>>> String hostname =3D getHostName(); >>>>>>>> >>>>>>>> zookClient =3D new ZookeeperClient(nodes, >>>>>>>> LEADERSHIP_NODE, hostname); >>>>>>>> zookClient.start(); >>>>>>>> >>>>>>>> } catch (Exception ex) { >>>>>>>> System.out.println (ex); >>>>>>>> System.exit(1); >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> public ZookeeperClient getZookClient() { >>>>>>>> return zookClient; >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> And here is my ZookeeperClient code - >>>>>>>> >>>>>>>> public class ZookeeperClient { >>>>>>>> >>>>>>>> private CuratorFramework client; >>>>>>>> private String latchPath; >>>>>>>> private String id; >>>>>>>> private LeaderLatch leaderLatch; >>>>>>>> >>>>>>>> public ZookeeperClient(String connString, String latchPath= , >>>>>>>> String id) { >>>>>>>> client =3D CuratorFrameworkFactory.newClient(connStrin= g, >>>>>>>> new ExponentialBackoffRetry(1000, Integer.MAX_VALUE)); >>>>>>>> this.id =3D id; >>>>>>>> this.latchPath =3D latchPath; >>>>>>>> } >>>>>>>> >>>>>>>> public void start() throws Exception { >>>>>>>> client.start(); >>>>>>>> >>>>>>>> client.getZookeeperClient().blockUntilConnectedOrTimedOut(); >>>>>>>> leaderLatch =3D new LeaderLatch(client, latchPath, id)= ; >>>>>>>> leaderLatch.start(); >>>>>>>> } >>>>>>>> >>>>>>>> public boolean isLeader() { >>>>>>>> return leaderLatch.hasLeadership(); >>>>>>>> } >>>>>>>> >>>>>>>> public Participant currentLeader() throws Exception { >>>>>>>> return leaderLatch.getLeader(); >>>>>>>> } >>>>>>>> >>>>>>>> public void close() throws IOException { >>>>>>>> leaderLatch.close(); >>>>>>>> client.close(); >>>>>>>> } >>>>>>>> >>>>>>>> public CuratorFramework getClient() { >>>>>>>> return client; >>>>>>>> } >>>>>>>> >>>>>>>> public String getLatchPath() { >>>>>>>> return latchPath; >>>>>>>> } >>>>>>>> >>>>>>>> public String getId() { >>>>>>>> return id; >>>>>>>> } >>>>>>>> >>>>>>>> public LeaderLatch getLeaderLatch() { >>>>>>>> return leaderLatch; >>>>>>>> } >>>>>>>> } >>>>>>>> >>>>>>>> And this is the way I am using it - >>>>>>>> >>>>>>>> ZookeeperLeaderTester zookClient =3D >>>>>>>> ZookeeperLeaderTester.getInstance().getZookClient(); >>>>>>>> if (zookClient.isLeader()) { >>>>>>>> // then do stuff >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > --001a11347914f156dc050cbd1741 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
The InterProcessMutex is essentia= lly a distributed lock. In each of your clients you just create an InterPro= cessMutex instance referring to the same ZK path

CuratorFramew= ork curator =3D ...
String lockPath =3D "/lockPath"= ;

InterProcessMutex mutex =3D new InterProcessMutex= (curator, lockPath);
try {
=C2=A0=C2=A0=C2=A0 //This= will block until the mutex is acquire.
=C2=A0=C2=A0=C2=A0 mu= tex.acquire();

=C2=A0=C2=A0=C2=A0 //Do your critical stuf= f
} finally {
=C2=A0=C2=A0=C2=A0 //Release the mutex=
=C2=A0=C2=A0=C2=A0 mutex.release();
}

<= /div>



On Fri, Jan 16, 2015 at 12:05 PM, Check = Peck <comptechgeeky@gmail.com> wrote:
What is the benefit I will have with Int= erProcessMutex? I have never use this before. Is there any example which I = can take a look?

On Thu, Jan 15, 2015 at 4:= 07 PM, Cameron McKenzie <mckenzie.cam@gmail.com> wrote:=
Yes, good point.

On F= ri, Jan 16, 2015 at 10:57 AM, Jordan Zimmerman <jordan@jordanzimm= erman.com> wrote:
But if you go = through that much trouble you might as well just use InterProcessMutex.

=
-JZ



On January 15, 2015 at 6:54:30 PM, Cameron Mc= Kenzie (mckenzi= e.cam@gmail.com) wrote:

<= /div>
If you use the callback as Jordan suggested, then you can just block on a latch, and then get this latch to be updated by the callback when it is notified that it's leader. Then you won't have to wait for some fixed amount of time, it will just block until it's leader.


On Fri, Jan 16, 2015 at 10:48 AM, Check Peck <comptechgeeky@gmail.com> wrote:
As of now, I am adding a sleep of 1 minute and it works fine before I check whether I am a leader or not.

On Thu, Jan 15, 2015 at 3:43 PM, Check Peck <comptechgeeky@gmail.com> wrote:
Yes that makes sense that 1 client will be leader. But suppose I have 5 background threads running in 5 different machines and each background thread is in different classes and I want to make sure that those 5 background threads are running from a single machine who is the leader so that's why we are doing that check whether I am the leader then do this.

Will this work if we add a Listener to leaderlatch?

On Thu, Jan 15, 2015 at 3:30 PM, Jordan Zimmerman <jordan@jordanzimmerman.com> wrote:
The problem with that is you have to wait until you are the leader. The benefit of LeaderSelector is that it has a callback that is invoked when you are the leader. Remember, you are in a multithreaded, multi client environment. Only 1 client is going to be the leader. Maybe what you are after is an InterProcessMutex?

-JZ



On January 15, 2015 at 6:24:06 PM, Check Peck (comptechgeeky= @gmail.com) wrote:

But didn't understand few things - How can I call something like this in my code=C2=A0 - I want to do stuff in my code by just checking whether I am the leader or not. And from the LeaderSelectorExample, I am not able to understand this.

if (zookClient.isLeader()) {

// then do stuff

}


On Thu, Jan 15, 2015 at 3:17 PM, Jordan Zimmerman <jordan@jordanzimmerman.com> wrote:
Oh - maybe I read the code too fast. I guess it doesn=E2=80=99t make more than one=E2=80=A6

There=E2=80=99s an example of LeaderSelector here:=C2=A0http://cur= ator.apache.org/curator-examples/index.html


On January 15, 2015 at 6:00:03 PM, Check Peck (comptechgeeky= @gmail.com) wrote:

Thanks Jordan for the input.

* Where do you see that I am creating new Curator instance for each Leader? I guess I am using one Curator instance for my application?
* Ok, I have commented out this line in ZookeeperClient class
* That's a good point, how would I use the listener or the leaderselector in my code base? If possible, can you provide an example?


On Thu, Jan 15, 2015 at 2:38 PM, Jordan Zimmerman <jordan@jordanzimmerman.com> wrote:
A few things:

* You don=E2=80=99t need to create a new Curator instance for each Leader. One Curator instance can be used for an application.
* Calling client.getZookeeperClient().blockUntilConnectedOrTimedOut(); is unnecessary
* Calling isLeader() immediately after starting the latch may not work. It takes time for the leader to get selected. LeaderLatch has a listener if you want to get notified. Alternatively, you can use LeaderSelector.

Hope this helps.

-Jordan



On January 15, 2015 at 5:25:26 PM, Check Peck (comptechgeeky= @gmail.com) wrote:

I am using Zookeeper for the leadership election process. I have three nodes zookeeper ensemble.

We have a node like this "/test/msn" on which we are doing the leadership election and it works fine and we have application servers running it in production and using "/test/msn" node for leadership. And this program is always running.

Now we created another node like this "/testpnl" in the same zookeeper servers. And we have another set of machines which is trying to do the leadership election on that node and whenever I run my program in production from one servers, it always returns back that the node is not leader? And I can see only one node inside "/testpnl" and it is the same node from which I am running my program?

I am using Curator 2.7.0 and the zookeeper version is 3.4.5 Is there anything wrong with my setup or zookeeper has some bug which I am not aware?

Is anything

=C2=A0=C2=A0=C2=A0 public class ZookeeperLeaderTester {

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private ZookeeperClient zookClient;

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private static final String ZOOK_PRODUCTION =3D "host1:2181,host2:2181,host3:2181";
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private static final String LEADERSHIP_NODE =3D "/testpnl";

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private static class Holder {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 static final ZookeeperLeaderTester INSTANCE =3D new ZookeeperLeaderTester();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public static ZookeeperLeaderTester getInstance() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return Holder.INSTANCE;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private ZookeeperLeaderTester() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 try {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 String hostname =3D getHostName();

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 zookClient =3D new ZookeeperClient(nodes, LEADERSHIP_NODE, hostname);
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 zookClient.start();

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 } catch (Exception ex) {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 System.out.println (ex);
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 System.exit(1);
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public ZookeeperClient getZookClient() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return zookClient;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0
And here is my ZookeeperClient code -

=C2=A0=C2=A0=C2=A0 public class ZookeeperClient {

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private CuratorFramework client;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private String latchPath;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private String id;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 private LeaderLatch leaderLatch;

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public ZookeeperClient(String connString, String latchPath, String id) {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 client =3D CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 this.id =3D id;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 this.latchPath =3D latchPath;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public void start() throws Exception {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 client.start();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 client.getZookeeperClient().blockUntilConnectedOrTimedOut();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 leaderLatch =3D new LeaderLatch(client, latchPath, id);
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 leaderLatch.start();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public boolean isLeader() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return leaderLatch.hasLeadership();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public Participant currentLeader() throws Exception {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return leaderLatch.getLeader();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public void close() throws IOException {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 leaderLatch.close();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 client.close();
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public CuratorFramework getClient() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return client;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public String getLatchPath() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return latchPath;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public String getId() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return id;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }

=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 public LeaderLatch getLeaderLatch() {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 return leaderLatch;
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0
And this is the way I am using it -

=C2=A0=C2=A0=C2=A0 ZookeeperLeaderTester zookClient =3D ZookeeperLeaderTester.getInstance().getZookClient();
=C2=A0=C2=A0=C2=A0 if (zookClient.isLeader()) {
=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 // then do stuff
=C2=A0=C2=A0=C2=A0 }








--001a11347914f156dc050cbd1741--