private void HostsChangedHandler(int serviceId) { var path = GetServicePath(serviceId); client.SubscribeChildrenChange(path, (ct, args) => { if (args.Type == EventType.NodeChildrenChanged) { logger.LogInformation($"Hosts changed on zookeeper. ServiceId={serviceId}"); var serviceSubscriberInfo = serviceSubscriberList[serviceId]; lock (hostsChangedLockObj) { var serviceProxy = serviceSubscriberInfo.ServiceProxy; var currentHosts = serviceSubscriberInfo.ConnectionInfos.Select(c => Utils.GetHostName(c.Host, c.Port)).ToList(); var deletedHosts = currentHosts.Except(args.CurrentChildrens); var insertedHosts = args.CurrentChildrens.Except(currentHosts); if (deletedHosts.Count() > 0) { HandleDeletedHosts(serviceId, deletedHosts, serviceSubscriberInfo); } if (insertedHosts.Count() > 0) { HandleInsertedHosts(serviceId, insertedHosts, serviceSubscriberInfo, path); } } } return(Task.CompletedTask); }); }
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); } } }
protected override async Task DoSubscribe(ServiceConfig config, Action <IList <ServiceConfig> > onChange) { var path = $"/dubbo/{config.ServiceName}/providers"; await CreatePath(path, true); var childs = await client.SubscribeChildrenChange(path, ((zk, args) => { var configs = args.CurrentChildrens.Select(child => ServiceConfig.ParseServiceUrl(HttpUtility.UrlDecode(child, Encoding.UTF8))).ToArray(); onChange(configs); return(Task.CompletedTask); })); onChange(childs.Select(child => ServiceConfig.ParseServiceUrl(HttpUtility.UrlDecode(child, Encoding.UTF8))) .ToArray()); Log.InfoFormat("subscribe {0} success.", path); }
public async Task SubscribeChildrenChange(string key, Action <NodeChildrenChangeArgs> action) { var keys = Data.Keys.Where(x => x.StartsWith(key, StringComparison.InvariantCultureIgnoreCase)); foreach (var k in keys) { var path = $"/{k.Replace(":", "/")}"; await _client.SubscribeChildrenChange(path, (client, args) => { if (args.Type != Watcher.Event.EventType.NodeDeleted) { Data[k] = null; } else { Data.Remove(k); } action.Invoke(args); return(Task.CompletedTask); }); } }
internal async Task HandleChildrenChange(IZookeeperClient client, NodeChildrenChangeArgs args) { Watcher.Event.EventType eventType = args.Type; var path = args.Path; var watcher = new ChildrenMonitorWatcher(path, _action); switch (eventType) { case Watcher.Event.EventType.NodeCreated: await client.SubscribeChildrenChange(path, watcher.HandleChildrenChange); break; case Watcher.Event.EventType.NodeDataChanged: try { var currentChildrens = new string[0]; if (args.CurrentChildrens != null && args.CurrentChildrens.Any()) { currentChildrens = args.CurrentChildrens.ToArray(); } _action(_currentData, currentChildrens); watcher.SetCurrentData(currentChildrens); } catch (KeeperException.NoNodeException) { _action(_currentData, new string[0]); watcher.SetCurrentData(new string[0]); } break; case Watcher.Event.EventType.NodeDeleted: _action(_currentData, new string[0]); watcher.SetCurrentData(new string[0]); break; } }
/// <summary> /// 订阅节点子节点变更 /// </summary> /// <param name="path">节点路径</param> /// <param name="listener">监听者</param> /// <returns></returns> public Task <IEnumerable <string> > SubscribeChildrenChange(string path, NodeChildrenChangeHandler listener) { return(client.SubscribeChildrenChange(path, listener)); }