public class MembershipLock
A Read-Write lock which is specific to a ZooKeeper-based membership protocol.
The basic idea is relatively straightforward: we want to use ZK to establish a distributed
lock, but we don't want to actually communicate with ZK unless we have to (i.e. for the write lock).
So this implementation is less of a true lock and more of a mechanism through which we can block
operations during a membership operation.
The basic algorithm is as follows:
To acquire the write lock:
1. To acquire "Write lock", write znode into specific lock directory.
2. If you are not the only writer attempting, then attach watch to LOWEST sequence node (i.e. standard ZooKeeper lock protocol)
3. Wait for all nodes to terminate local reads; once that is done, they will add to a CYCLIC reads location.
4. Once all nodes are added to the cyclic reads location, the write lock is acquired and can proceed.
To acquire the read lock:
1. Attach watcher to write lock location.
A. If no nodes are present in the WL location, then read lock can be acquired locally.
1. attach watcher to a random WL node in the list
2. add node to CYCLIC reads location
3. block until released.
This is suitable for use whenever the expected "reads" are happening MUCH more frequently than the expected "writes" (as in the case of a
membership lock). If those situations are reversed, then you are no good.
Note that the read lock is "Non-reentrant", in that it can be released from a different thread than it was acquired in.
This class is cluster-safe, and is therefore also thread-safe