constructor
executorService thread pool to use 線程池/默認線程池爲守護線程
* @param listener listener LeaderSelectorListener 監聽器
*/
public LeaderSelector (CuratorFramework client, String leaderPath, CloseableExecutorService executorService, LeaderSelectorListener listener)
{
this .client = client;
this .listener = new WrappedListener(this , listener);
hasLeadership = false ;
this .executorService = executorService;
mutex = new InterProcessMutex(client, leaderPath)
{
@Override
protected byte [] getLockNodeBytes ()
{
return (id.length() > 0 ) ? getIdBytes(id) : null ;
}
};
}
start
/**
* Attempt leadership. This attempt is done in the background - i.e. this method returns
* immediately.<br><br>
* <b>IMPORTANT: </b> previous versions allowed this method to be called multiple times. This
* is no longer supported. Use {@link #requeue()} for this purpose.
*/
public void start ()
{
client.getConnectionStateListenable().addListener(listener);
requeue();
}
internalRequeue
private synchronized boolean internalRequeue ()
{
if ( !isQueued && (state.get() == State.STARTED) )
{
isQueued = true ;
Future<Void> task = executorService.submit(new Callable<Void>()
{
@Override
public Void call () throws Exception
{
try
{
doWorkLoop();
}
finally
{
clearIsQueued();
if ( autoRequeue.get() )
{
internalRequeue();
}
}
return null ;
}
});
ourTask.set(task);
return true ;
}
return false ;
}
doWork
@VisibleForTesting
void doWork() throws Exception
{
hasLeadership = false ;
try
{
mutex.acquire();
hasLeadership = true ;
try
{
if ( debugLeadershipLatch != null )
{
debugLeadershipLatch.countDown();
}
if ( debugLeadershipWaitLatch != null )
{
debugLeadershipWaitLatch.await();
}
listener.takeLeadership(client);
}
catch ( InterruptedException e )
{
Thread.currentThread().interrupt();
throw e;
}
catch ( Throwable e )
{
ThreadUtils.checkInterrupted(e);
}
finally
{
clearIsQueued();
}
}
catch ( InterruptedException e )
{
Thread.currentThread().interrupt();
throw e;
}
finally
{
if ( hasLeadership )
{
hasLeadership = false ;
try
{
mutex.release();
}
catch ( Exception e )
{
ThreadUtils.checkInterrupted(e);
log.error("The leader threw an exception" , e);
}
}
}
}