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 <wander4...@gmail.com> 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 <wander4...@gmail.com> --- .../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