private object LockOperation() { do { if (id == null) { long sessionId = Zookeeper.SessionId; string prefix = "x-" + sessionId + "-"; FindPrefixInChildren(prefix, Zookeeper, dir); idName = new ZNodeName(id); } if (id == null) { continue; } List <string> names = Zookeeper.GetChildren(dir, false); if (names.IsEmpty()) { LOG.Warn("No children in: " + dir + " when we've just " + "created one! Lets recreate it..."); // lets force the recreation of the id id = null; } else { // lets sort them explicitly (though they do seem to come back in order ususally :) var sortedNames = new SortedSet <ZNodeName>(); foreach (string name in names) { sortedNames.Add(new ZNodeName(dir.Combine(name))); } ownerId = sortedNames.First().Name; SortedSet <ZNodeName> lessThanMe = sortedNames.HeadSet(idName); if (!lessThanMe.IsEmpty()) { ZNodeName lastChildName = lessThanMe.Last(); lastChildId = lastChildName.Name; if (LOG.IsDebugEnabled) { LOG.Debug("watching less than me node: " + lastChildId); } Stat stat = Zookeeper.Exists(lastChildId, new LockWatcher(this)); if (stat != null) { return(false); } LOG.Warn("Could not find the stats for less than me: " + lastChildName.Name); } else { if (Owner) { OnLockAcquired(); return(true); } } } } while (id == null); return(false); }
public bool RunForLeader() { long sessionId = Zookeeper.SessionId; string prefix = "election-" + sessionId + "-"; var names = Zookeeper.GetChildren(path, false); // See whether we have already run for election in this process foreach (string name in names) { if (name.StartsWith(prefix)) { id = name; if (LOG.IsDebugEnabled) { LOG.DebugFormat("Found id created last time: {0}", id); } } } if (id == null) { id = Zookeeper.Create(path.Combine(prefix), data, Acl, CreateMode.EphemeralSequential); if (LOG.IsDebugEnabled) { LOG.DebugFormat("Created id: {0}", id); } } idName = new ZNodeName(id); names = Zookeeper.GetChildren(path, false); var sortedNames = new SortedSet <ZNodeName>(); foreach (var name in names) { sortedNames.Add(new ZNodeName(name)); } var priors = sortedNames.HeadSet(idName); if (priors.Count == 0) { throw new InvalidOperationException("Count of priors is 0, but should at least include this node."); } if (priors.Count == 1) { IsOwner = true; watcher.TakeLeadership(); return(true); } // only watch the node directly before us ZNodeName penultimate = null, last = null; foreach (var name in sortedNames) { penultimate = last; last = name; } if (penultimate == null) { throw new InvalidOperationException("Penultimate value in priors is null, but count shoudl have been at least 2."); } var penultimatePath = path.Combine(penultimate.Name); if (Zookeeper.Exists(penultimatePath, new LeaderWatcher(Zookeeper, this, penultimatePath, watcher, path, id)) == null) { IsOwner = true; watcher.TakeLeadership(); return(true); } return(false); }