public async Task SubscribeChildrenChangeTest()
        {
            var path  = $"/{DateTime.Now:yyyy_MM_dd_HH_mm_ss_ff}";
            var path2 = $"{path}/123";

            try
            {
                if (await _client.ExistsAsync(path))
                {
                    await _client.DeleteRecursiveAsync(path);
                }

                var types = new List <Watcher.Event.EventType>();

                var semaphore = new Semaphore(0, 2);

                await _client.SubscribeDataChange(path, (client, args) =>
                {
                    if (args.Type == Watcher.Event.EventType.NodeCreated)
                    {
                        semaphore.Release();
                    }
                    return(Task.CompletedTask);
                });

                await _client.SubscribeChildrenChange(path, (client, args) =>
                {
                    types.Add(args.Type);
                    semaphore.Release();
                    return(Task.CompletedTask);
                });

                await _client.CreatePersistentAsync(path, null);

                semaphore.WaitOne(10000);
                await _client.CreatePersistentAsync(path2, null);

                semaphore.WaitOne(10000);
                Assert.Equal(Watcher.Event.EventType.NodeChildrenChanged, types[0]);
            }
            finally
            {
                if (await _client.ExistsAsync(path))
                {
                    await _client.DeleteRecursiveAsync(path);
                }
            }
        }
Beispiel #2
0
        public async Task SubscribeDataChangeTest()
        {
            var path = $"/{DateTime.Now:yyyy_MM_dd_HH_mm_ss_ff}";

            try
            {
                if (await _client.ExistsAsync(path))
                {
                    await _client.DeleteAsync(path);
                }

                var types     = new List <Watcher.Event.EventType>();
                var waitEvent = new AutoResetEvent(false);

                await _client.SubscribeDataChange(path, (client, args) =>
                {
                    types.Add(args.Type);
                    waitEvent.Set();
                    return(Task.CompletedTask);
                });

                //created
                await _client.CreateEphemeralAsync(path, null);

                waitEvent.WaitOne(10000);

                //Assert.Equal(Watcher.Event.EventType.NodeCreated, types[0]);

                //modify
                await _client.SetDataAsync(path, new byte[] { 1 });

                waitEvent.WaitOne(10000);
                // Assert.Equal(Watcher.Event.EventType.NodeDataChanged, types[1]);

                //deleted
                await _client.DeleteAsync(path);

                waitEvent.WaitOne(10000);
                //  Assert.Equal(Watcher.Event.EventType.NodeDeleted, types[2]);
            }
            finally
            {
                if (await _client.ExistsAsync(path))
                {
                    await _client.DeleteAsync(path);
                }
            }
        }
        public async Task StartAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            var existPath = await _client.ExistsAsync(ListenerPath);

            if (!existPath)
            {
                await _client.CreateRecursiveAsync(ListenerPath, Encoding.UTF8.GetBytes("Bucket.Listener"));
            }
            await _client.SubscribeDataChange(ListenerPath, async (ct, args) =>
            {
                if (!_isSubscribe)
                {
                    return;
                }
                var currentData = Encoding.UTF8.GetString(args.CurrentData.ToArray());
                if (!string.IsNullOrWhiteSpace(currentData))
                {
                    var command = JsonConvert.DeserializeObject <Values.NetworkCommand>(currentData);
                    if (args.Path.ToLower() == ListenerPath.ToLower())
                    {
                        switch (args.Type)
                        {
                        case Watcher.Event.EventType.NodeDataChanged:
                            await _extractCommand.ExtractCommandMessage(command);
                            break;
                        }
                    }
                }
            });

            _isSubscribe = true;
        }
        /// <summary>
        /// 监听指定的节点
        /// </summary>
        /// <param name="node">节点名称</param>
        /// <param name="callback">节点数据更改或者节点被删除时会触发该事件</param>
        /// <returns>Task</returns>
        public Task Listen(string node, CacheCallback <string> callback)
        {
            NodeDataChangeHandler handler = null;

            handler = (ct, args) =>
            {
                //节点被删除或者节点数据改动时清理该节点对应的缓存数据
                if (args.Type == Watcher.Event.EventType.NodeDataChanged || args.Type == Watcher.Event.EventType.NodeDeleted)
                {
                    if (callback != null)
                    {
                        callback(args.Path);
                    }
                }
                return(Task.CompletedTask);
            };


            NodeDataChangeHandler handlerLast = null;

            if (_handlerRecord.ContainsKey(node))
            {
                handlerLast = _handlerRecord[node];
            }
            if (handlerLast != null)
            {
                //取消侦听
                _zkClient.UnSubscribeDataChange(node, handlerLast);
            }
            _handlerRecord[node] = handler;
            Task task = _zkClient.SubscribeDataChange(node, handler);

            return(task);
        }
Beispiel #5
0
        private async Task <bool> SetRouteAsync(ServiceRouteDescriptor route, IZookeeperClient zooKeeperClient)
        {
            try
            {
                bool isSetRoute = false;
                _logger.LogDebug($"准备添加{route.ServiceDescriptor.Id}服务路由。");
                var zooKeeperClients = await _zookeeperClientProvider.GetZooKeeperClients();
                await CreateSubdirectory(zooKeeperClient, _configInfo.RoutePath);

                var path = _configInfo.RoutePath;
                if (!path.EndsWith("/"))
                {
                    path += "/";
                }

                var nodePath = $"{path}{route.ServiceDescriptor.Id}";
                var nodeData = _serializer.Serialize(route);
                _logger.LogDebug($"服务路由内容为:{Encoding.UTF8.GetString(nodeData)}。");
                if (!nodeWatchers.ContainsKey(nodePath))
                {
                    var watcher = nodeWatchers.GetOrAdd(nodePath, f => new NodeMonitorWatcher(path, async(oldData, newData) => await NodeChange(oldData, newData)));
                    await zooKeeperClient.SubscribeDataChange(nodePath, watcher.HandleNodeDataChange);
                }
                if (!await zooKeeperClient.ExistsAsync(nodePath))
                {
                    _logger.LogDebug($"节点:{nodePath}不存在将进行创建。");
                    await zooKeeperClient.CreateAsync(nodePath, nodeData, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                }
                else
                {
                    var onlineData = (await zooKeeperClient.GetDataAsync(nodePath)).ToArray();
                    if (!DataEquals(nodeData, onlineData))
                    {
                        await zooKeeperClient.SetDataAsync(nodePath, nodeData);

                        _logger.LogDebug($"{nodePath}节点的缓存的服务路由与服务注册中心不一致,路由数据已被更新。");
                        isSetRoute = true;
                    }
                }

                return(isSetRoute);
            }
            catch (Exception ex)
            {
                _logger.LogError($"{route.ServiceDescriptor.Id}服务的路由注册失败,原因:{ex.Message}");
                return(false);
            }
        }
Beispiel #6
0
        public async Task SubscribeDataChange(string key, Action <NodeDataChangeArgs> action)
        {
            var keys = Data.Keys.Where(x => x.StartsWith(key, StringComparison.InvariantCultureIgnoreCase));

            foreach (var k in keys)
            {
                var path = $"/{k.Replace(":", "/")}";
                await _client.SubscribeDataChange(path, (client, args) =>
                {
                    if (args.Type != Watcher.Event.EventType.NodeDeleted)
                    {
                        Data[k] = Encoding.UTF8.GetString(args.CurrentData.ToArray());
                    }
                    else
                    {
                        Data.Remove(k);
                    }

                    action.Invoke(args);
                    return(Task.CompletedTask);
                });
            }
        }
 /// <summary>
 /// 订阅节点数据变更
 /// </summary>
 /// <param name="path">节点路径</param>
 /// <param name="listener">监听者</param>
 public void SubscribeDataChange(string path, NodeDataChangeHandler listener)
 {
     client.SubscribeDataChange(path, listener);
 }