Curator hierarchy lock (overlapping locks)
I was able to successfully acquire the lock /ads/lock/0-test1
and then failed to acquire the lock/ads/lock
How can I solve this?
InterProcessMutex lock1 = new InterProcessMutex(client, "/ads/lock/0-test1");
if(lock1.acquire(30000, TimeUnit.MILLISECONDS)){
InterProcessMutex lock2 = new InterProcessMutex(client, "/ads/lock");
if(lock2.acquire(30000, TimeUnit.MILLISECONDS)) { //Failing
...
}
}
Update: This is the gist of what's going on in this https://github.com/Microsoft/Cluster-Partition -Rebalancer-For-Kafka / ZookeeperBackedAdoptionLogicImpl.java The locks on line 250 (verbose path) and 299 (root path) are sequential ... Thus, when another instance tries to block the verbose path (250), the blocking will fail because the root path (299) is blocked. The logic is valid, but the root lock is never reached
Update 2: I wrote a small program to test if overlapping locks and .
public class LockTesting {
public static final String ROOT_LOCK = "/locks";
public static final String CHILD_LOCK = ROOT_LOCK+"/child";
private static CuratorFramework client;
public static void main(String[] args) throws Exception {
client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new ExponentialBackoffRetry(1000, 30));
client.start();
InterProcessMutex lock1 = new InterProcessMutex(client, CHILD_LOCK);
if (lock1.acquire(30000, TimeUnit.MILLISECONDS)) {
System.out.println("Child Locked");
InterProcessMutex lock2 = new InterProcessMutex(client, ROOT_LOCK);
if (lock2.acquire(30000, TimeUnit.MILLISECONDS)) {
System.out.println("Root Locked");
}
}
}
}
source to share
While not explicitly documented (but see technote 7 ), the mechanisms used by the curator to create the lock depend on the child nodes of the particular znode path. InterProcessMutex
is an implementation of the zookeeper locking recipe that has this data included in the documentation. When trying to use a hierarchical construct like this, you are essentially tinkering with the internal locking structure.
The lock path should be considered an "object" whose internal znodes are not available and can be changed.
Update response
This code is indeed an example of such misuse.
Reply to Update2
Yes, sometimes it can work. But that depends on internal implementation details InterProcessMutex
. You will find that this will work with some lock names but not with others, or you will have undefined behavior.
source to share