Skip to content

Commit

Permalink
CURATOR-537: Fix effective path can be used as a fencing token of Lea…
Browse files Browse the repository at this point in the history
…derLatch (#414)

This is a follow up to #324.

ourPath can be modified after it's retrived in checkLeadership and before isLeader saves it by ourPath.get() again - if the connection reset and node be recreated.

To avoid handling multiple concurrent cases, this patch simply saves the last node is leader as the localOurPath so that it's always the last valid fencing token - it can be verified as invalid later, but never false valid.

Signed-off-by: tison <[email protected]>
  • Loading branch information
tisonkun authored Apr 29, 2022
1 parent 5ca31e3 commit f1f9d5f
Showing 1 changed file with 23 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class LeaderLatch implements Closeable
private final AtomicReference<State> state = new AtomicReference<State>(State.LATENT);
private final AtomicBoolean hasLeadership = new AtomicBoolean(false);
private final AtomicReference<String> ourPath = new AtomicReference<String>();
private final AtomicReference<String> lastPathIsLeader = new AtomicReference<String>();
private final StandardListenerManager<LeaderLatchListener> listeners = StandardListenerManager.standard();
private final CloseMode closeMode;
private final AtomicReference<Future<?>> startTask = new AtomicReference<Future<?>>();
Expand Down Expand Up @@ -486,13 +487,34 @@ public boolean hasLeadership()
* returned is not guaranteed to be valid at any point in the future as internal
* state changes might require the instance to delete and create a new path.
*
* However, the existence of <code>ourPath</code> doesn't mean that this instance
* holds leadership.
*
* @see #getLastPathIsLeader
*
* @return lock node path or <code>null</code>
*/
public String getOurPath()
{
return ourPath.get();
}

/**
* Return last of this instance's lock node path that was leader ever.
* IMPORTANT: this instance owns the path returned. This method is meant for reference only.
* Also, it is possible for <code>null</code> to be returned (for this instance never becomes
* a leader). The path, if any, returned is not guaranteed to be valid at any point in the future
* as internal state changes might require the instance to delete the path.
*
* The existence of <code>lastPathIsLeader</code> means that this instance holds leadership.
*
* @return last lock node path that was leader ever or <code>null</code>
*/
public String getLastPathIsLeader()
{
return lastPathIsLeader.get();
}

@VisibleForTesting
volatile CountDownLatch debugResetWaitLatch = null;

Expand Down Expand Up @@ -571,6 +593,7 @@ private void checkLeadership(List<String> children) throws Exception
}
else if ( ourIndex == 0 )
{
lastPathIsLeader.set(localOurPath);
setLeadership(true);
}
else
Expand Down

0 comments on commit f1f9d5f

Please sign in to comment.