示例#1
0
        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 watchPath = _path.Combine(penultimate.Name);
            if (Zookeeper.Exists(watchPath, new LeaderWatcher(this, watchPath, _watcher)) == null)
            {
                IsOwner = true;
                _watcher.TakeLeadership();
                return true;
            }
            return false;
        }