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

Reply via email to