This is an automated email from the ASF dual-hosted git repository.
tison pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/curator.git
The following commit(s) were added to refs/heads/master by this push:
new f1f9d5f8 CURATOR-537: Fix effective path can be used as a fencing
token of LeaderLatch (#414)
f1f9d5f8 is described below
commit f1f9d5f8a09eee0ce288aa39c6a47700ae3fcd07
Author: tison <[email protected]>
AuthorDate: Fri Apr 29 09:25:55 2022 +0800
CURATOR-537: Fix effective path can be used as a fencing token of
LeaderLatch (#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]>
---
.../framework/recipes/leader/LeaderLatch.java | 23 ++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git
a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java
b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java
index 7d9ca3ca..5d1c249b 100644
---
a/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java
+++
b/curator-recipes/src/main/java/org/apache/curator/framework/recipes/leader/LeaderLatch.java
@@ -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<?>>();
@@ -486,6 +487,11 @@ public class LeaderLatch implements Closeable
* 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()
@@ -493,6 +499,22 @@ public class LeaderLatch implements Closeable
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;
@@ -571,6 +593,7 @@ public class LeaderLatch implements Closeable
}
else if ( ourIndex == 0 )
{
+ lastPathIsLeader.set(localOurPath);
setLeadership(true);
}
else