Example #1
0
        public async Task Lock(string lockNode)
        {
            var node = $"{config.LockPath}/${lockNode}";

            await this.CreatNodeIfNotExist(node);

            var path = $"{config.LockPath}/${lockNode}/${config.Name}-";

            this.nodePath = await zooKeeper.createAsync(
                path,
                this.config.Name.ToBytes(),
                this.acls,
                ZK.CreateMode.EPHEMERAL_SEQUENTIAL);

            var index    = nodePath.GetIndex();
            var children = await zooKeeper.getChildrenAsync(node);

            var childrenIndex = children.Children.Select(p => new { Node = p, Index = p.GetIndex() }).OrderBy(p => p.Index).ToList();

            if (childrenIndex.First().Index == index)
            {
                Console.WriteLine($"{this.config.Name} Begin Lock");
                return;
            }

            var targetNode = string.Empty;

            for (int i = 0; i < childrenIndex.Count; i++)
            {
                if (childrenIndex[i].Index == index)
                {
                    targetNode = childrenIndex[i - 1].Node;
                    break;
                }
            }
            if (string.IsNullOrEmpty(targetNode))
            {
                throw new Exception("Node Get Error");
            }
            var tcs = new TaskCompletionSource <bool>();

            Console.WriteLine($"{this.config.Name} Wait for {node}/{targetNode}");
            var waitNode = await zooKeeper.existsAsync(
                $"{node}/{targetNode}",
                new WaitWatcher($"{node}/{targetNode}", tcs, e => e.get_Type() == EventType.NodeDeleted || e.getState() == KeeperState.Disconnected));

            if (waitNode != null)
            {
                await Task.WhenAny(Task.Delay(Timeout.Infinite), tcs.Task);
            }
            Console.WriteLine($"{this.config.Name} Begin Lock");
            return;
        }
        public async Task <int> WatchEpochAsync(Watcher watcher)
        {
            var actionToPerform = "set a watch on epoch";

            while (true)
            {
                await BlockUntilConnected(actionToPerform);

                try
                {
                    var stat = await zookeeper.existsAsync(this.epochPath, watcher);

                    return(stat.getVersion());
                }
                catch (KeeperException.NoNodeException e)
                {
                    throw new ZkInvalidOperationException($"Could not {actionToPerform} as the epoch node does not exist.", e);
                }
                catch (KeeperException.ConnectionLossException)
                {
                    // do nothing, the next iteration will try again
                }
                catch (KeeperException.SessionExpiredException e)
                {
                    throw new ZkSessionExpiredException($"Could not {actionToPerform} as the session has expired: ", e);
                }
                catch (Exception e)
                {
                    throw new ZkInvalidOperationException($"Could not {actionToPerform} due to an unexpected error", e);
                }
            }
        }
Example #3
0
        public async Task <bool> ReleaseLock(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            var sta = await _zooKeeper.existsAsync($"/PessimisticLock/{key}", new WatcherSample());

            if (sta == null)
            {
                return(true);
            }

            var lockData = await _zooKeeper.getDataAsync($"/PessimisticLock/{key}", new WatcherSample());

            var mark = Encoding.UTF8.GetString(lockData.Data) == key;

            if (mark)
            {
                await _zooKeeper.deleteAsync($"/PessimisticLock/{key}", sta.getVersion());
            }

            return(true);
        }
        private async Task SetupKey(string featureKey)
        {
            var path = GetPathForKey(featureKey);

/*            await TryAndRetry(async z =>
 *          {
 *              var doLoop = false;
 *              do
 *              {
 */
            try
            {
                var res = await zooKeeper.getDataAsync(path, watcher);

                OnZookeeperEntryChanged(path, res.Data == null ? null : Encoding.UTF8.GetString(res.Data));
            }
            catch (KeeperException.NoNodeException)
            {
                // setup watcher to catch node creation
                if (await zooKeeper.existsAsync(path, watcher) == null)
                {
                    OnZookeeperEntryChanged(path, null);
                }
//                        else
//                            doLoop = true; // if entry created in between
            }

/*
 *              } while (doLoop);
 *
 *          });*/
        }
        private async Task SetupConnectionAsync()
        {
            zooKeeper = new org.apache.zookeeper.ZooKeeper(connectionString, 100000, new ZookeeperWatcher());
            org.apache.zookeeper.ZooKeeper.LogToFile  = false;
            org.apache.zookeeper.ZooKeeper.LogToTrace = true;

            var root = await zooKeeper.existsAsync("/");

            if (root == null)
            {
                if (!createStoreIfNeeded)
                {
                    throw new InvalidOperationException("Store does not exist");
                }

                await zooKeeper.createAsync("/", null, Z.ZooDefs.Ids.OPEN_ACL_UNSAFE, Z.CreateMode.PERSISTENT);
            }

            await CreateIfNotExist(zooKeeper, prefix);

            if (useWatchdog)
            {
                await CreateIfNotExist(zooKeeper, watchdogPrefix);
            }

            watcher = new FeatureWatcher(zooKeeper, OnZookeeperEntryChanged);
            if (useWatchdog)
            {
                await SetupWatchdog();
            }
            localView.Clear();
        }
Example #6
0
        public async Task EnsurePathAsync(string znodePath, byte[] bytesToSet = null)
        {
            string actionToPerform = $"ensure path {znodePath}";
            bool   succeeded       = false;

            while (!succeeded)
            {
                await BlockUntilConnected(actionToPerform);

                try
                {
                    Stat znodeStat = await zookeeper.existsAsync(znodePath);

                    if (znodeStat == null)
                    {
                        if (bytesToSet == null)
                        {
                            bytesToSet = Encoding.UTF8.GetBytes("0");
                        }

                        await zookeeper.createAsync(znodePath,
                                                    bytesToSet,
                                                    ZooDefs.Ids.OPEN_ACL_UNSAFE,
                                                    CreateMode.PERSISTENT);
                    }

                    succeeded = true;
                }
                catch (KeeperException.NodeExistsException)
                {
                    succeeded = true; // the node exists which is what we want
                }
                catch (KeeperException.ConnectionLossException)
                {
                    // do nothing, will try again in the next iteration
                }
                catch (KeeperException.SessionExpiredException e)
                {
                    throw new ZkSessionExpiredException($"Could not {actionToPerform} as the session has expired.", e);
                }
                catch (Exception e)
                {
                    throw new ZkInvalidOperationException($"Could not {actionToPerform} due to an unexpected error", e);
                }
            }
        }
        protected static void CheckVersions(org.apache.zookeeper.ZooKeeper client, string rootNode, int version, int cVersion)
        {
            var currentStat = client.existsAsync(rootNode).GetAwaiter().GetResult();

            currentStat.getVersion().Should().Be(version);
            currentStat.getCversion().Should().Be(cVersion);
            //currentStat.Version.Should().Be(version);
            //currentStat.Cversion.Should().Be(cVersion);
        }
        protected static void EnsureNodeDoesNotExist(string path, org.apache.zookeeper.ZooKeeper anotherClient)
        {
            var existResult = anotherClient.existsAsync(path).GetAwaiter().GetResult();

            existResult.Should().BeNull();
            //existResult.EnsureSuccess();
            //existResult.Path.Should().Be(path);
            //existResult.Status.Should().Be(ZooKeeperStatus.Ok);
            //existResult.Payload.Should().BeNull();
        }
Example #9
0
        public PessimisticLockV2(org.apache.zookeeper.ZooKeeper zooKeeper)
        {
            _zooKeeper = zooKeeper;
            var node = _zooKeeper.existsAsync("/PessimisticLockV2").Result;

            if (node == null)
            {
                Task.WaitAll(_zooKeeper.createAsync("/PessimisticLockV2", null, ZooDefs.Ids.OPEN_ACL_UNSAFE,
                                                    CreateMode.PERSISTENT));
            }
        }
Example #10
0
        public async Task RefreshAsync()
        {
            var connDic = new Dictionary <string, string>();

            var isExisted = await _zooKeeper.existsAsync("/connections");

            if (isExisted == null)
            {
                await _zooKeeper.createAsync("/connections", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }

            var connResult = await _zooKeeper.getChildrenAsync("/connections", new ConnectionWatcher(this));

            foreach (var conn in connResult.Children)
            {
                var connData = await _zooKeeper.getDataAsync($"/connections/{conn}/value");

                var connStr = Encoding.UTF8.GetString(connData.Data);
                connDic[conn] = connStr;
            }

            _cache.Set("connections", connDic);
        }
Example #11
0
 public async Task <bool> ExistsAsync(string path, bool watch)
 {
     return(await _zooKeeper.existsAsync(path, watch) != null);
 }
Example #12
0
        /// <summary>
        /// 获取锁
        /// </summary>
        /// <param name="millisecondsTimeout">等待时间</param>
        /// <returns></returns>
        public async Task <bool> TryLock(int millisecondsTimeout = 0)
        {
            try
            {
                zooKeeper = new org.apache.zookeeper.ZooKeeper("127.0.0.1", 50000, new MyWatcher());

                //创建锁节点
                if (await zooKeeper.existsAsync("/Locks") == null)
                {
                    await zooKeeper.createAsync("/Locks", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                }

                //新建一个临时锁节点
                lockNode = await zooKeeper.createAsync("/Locks/Lock_", null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

                //获取锁下所有节点
                var lockNodes = await zooKeeper.getChildrenAsync("/Locks");

                lockNodes.Children.Sort();

                //判断如果创建的节点就是最小节点 返回锁
                if (lockNode.Split("/").Last() == lockNodes.Children[0])
                {
                    return(true);
                }
                else
                {
                    //当前节点的位置
                    var location = lockNodes.Children.FindIndex(n => n == lockNode.Split("/").Last());
                    //获取当前节点 前面一个节点的路径
                    var frontNodePath = lockNodes.Children[location - 1];
                    //在前面一个节点上加上Watcher ,当前面那个节点删除时,会触发Process方法
                    await zooKeeper.getDataAsync("/Locks/" + frontNodePath, myWatcher);

                    //如果时间为0 一直等待下去
                    if (millisecondsTimeout == 0)
                    {
                        myWatcher.AutoResetEvent.WaitOne();
                    }
                    else //如果时间不为0 等待指定时间后,返回结果
                    {
                        var result = myWatcher.AutoResetEvent.WaitOne(millisecondsTimeout);

                        if (result)//如果返回True,说明在指定时间内,前面的节点释放了锁(但是)
                        {
                            //获取锁下所有节点
                            lockNodes = await zooKeeper.getChildrenAsync("/Locks");

                            //判断如果创建的节点就是最小节点 返回锁
                            if (lockNode.Split("/").Last() == lockNodes.Children[0])
                            {
                                return(true);
                            }
                            else
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }
            }
            catch (KeeperException e)
            {
                await UnLock();

                throw e;
            }
            return(false);
        }