/// <summary> /// get zook client /// </summary> /// <param name="configPath"></param> /// <param name="sectionName"></param> /// <param name="clientName"></param> /// <returns></returns> static public IZookClient Get(string configPath, string sectionName, string clientName) { string key = string.Concat(configPath ?? string.Empty, sectionName, clientName); _locker.EnterReadLock(); try { IZookClient client = null; if (_dicClients.TryGetValue(key, out client)) { return(client); } } finally { _locker.ExitReadLock(); } _locker.EnterWriteLock(); try { IZookClient client = null; if (_dicClients.TryGetValue(key, out client)) { return(client); } client = ZookClientFactory.Create(configPath, sectionName, clientName); _dicClients[key] = client; return(client); } finally { _locker.ExitWriteLock(); } }
/// <summary> /// new /// </summary> /// <param name="port"></param> /// <param name="serviceType"></param> /// <param name="zkConfigPath"></param> /// <param name="zkConfigName"></param> /// <param name="zNode"></param> /// <param name="owner"></param> public ZookeeperRegistry(int port, string serviceType, string zkConfigPath, string zkConfigName, string zNode, string owner) { if (string.IsNullOrEmpty(serviceType)) throw new ArgumentNullException("serviceType"); if (string.IsNullOrEmpty(zkConfigPath)) throw new ArgumentNullException("zkConfigPath"); if (string.IsNullOrEmpty(zkConfigName)) throw new ArgumentNullException("zkConfigName"); if (string.IsNullOrEmpty(zNode)) throw new ArgumentNullException("zNode"); this._zk = ZookClientPool.Get(zkConfigPath, "zookeeper", zkConfigName); this.RegisterZNode(new NodeInfo[] { new NodeInfo(string.Concat("/", zNode), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent), new NodeInfo(string.Concat("/", zNode, "/providers"), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent) }); this._sessionNode = new SessionNode(this._zk, string.Concat("/", zNode, "/providers/", Uri.EscapeDataString(string.Format( @"thrift2://{0}:{1}/{2}?anyhost=true&application={3}&dispatcher=message&dubbo=2.5.1& interface={2}&loadbalance=roundrobin&methods={7}&owner={4}&pid={5}&revision=0.0.2-SNAPSHOT& side=provider&threads=100×tamp={6}", IPUtility.GetLocalIntranetIP().ToString(), port.ToString(), zNode, Process.GetCurrentProcess().ProcessName, owner ?? "", Process.GetCurrentProcess().Id.ToString(), Date.ToMillisecondsSinceEpoch(DateTime.UtcNow).ToString(), string.Join(",", Type.GetType(serviceType).GetInterfaces()[0].GetMethods().Select(c => c.Name).ToArray())))), null, IDs.OPEN_ACL_UNSAFE); }
/// <summary> /// 批量创建一组节点 /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="index"></param> /// <param name="callback">当所有节点创建完毕时的回调</param> static private void TryEnsureCreate(IZookClient zk, NodeInfo[] nodes, int index, Action callback) { if (index >= nodes.Length) { if (callback != null) { callback(); } return; } var currNode = nodes[index]; zk.Create(currNode.Path, currNode.Data, currNode.ACL, currNode.CreateMode).ContinueWith(c => { if (c.IsFaulted) { var kex = c.Exception.InnerException as KeeperException; if (kex == null || kex.Error != Data.ZoookError.NODEEXISTS) { TaskEx.Delay(new Random().Next(1000, 3000), () => TryEnsureCreate(zk, nodes, index, callback)); return; } } TryEnsureCreate(zk, nodes, index + 1, callback); }); }
/// <summary> /// try create nodes /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <returns></returns> static public Task TryCreate(IZookClient zk, NodeInfo[] nodes) { if (zk == null) throw new ArgumentNullException("zk"); if (nodes == null || nodes.Length == 0) throw new ArgumentNullException("nodes"); var source = new TaskCompletionSource<bool>(); TryCreate(zk, nodes, 0, source); return source.Task; }
/// <summary> /// new /// </summary> /// <param name="zk"></param> /// <param name="path"></param> /// <param name="data"></param> /// <param name="acl"></param> /// <exception cref="ArgumentNullException">zk is null.</exception> public SessionNode(IZookClient zk, string path, byte[] data, Data.ACL[] acl) { if (zk == null) throw new ArgumentNullException("zk"); this._zk = zk; this._zk.KeeperStateChanged += new KeeperStateChangedHandler(this.KeeperStateChanged); this._nodeInfo = new NodeInfo(path, data, acl, Data.CreateModes.Ephemeral); this.CreateNode(); }
/// <summary> /// try create node /// </summary> /// <param name="zk"></param> /// <param name="node"></param> /// <returns></returns> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">node is null.</exception> static public Task TryCreate(IZookClient zk, NodeInfo node) { if (zk == null) throw new ArgumentNullException("zk"); if (node == null) throw new ArgumentNullException("node"); return zk.Create(node.Path, node.Data, node.ACL, node.CreateMode).ContinueWith(c => { var ex = c.Exception.InnerException as KeeperException; if (ex != null && ex.Error == Data.ZoookError.NODEEXISTS) return; throw c.Exception.InnerException; }, TaskContinuationOptions.OnlyOnFaulted); }
/// <summary> /// 批量创建一组节点 /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="callback">当所有节点创建完毕时的回调</param> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">nodes is null or empty.</exception> static public void TryEnsureCreate(IZookClient zk, NodeInfo[] nodes, Action callback) { if (zk == null) { throw new ArgumentNullException("zk"); } if (nodes == null || nodes.Length == 0) { throw new ArgumentNullException("nodes"); } TryEnsureCreate(zk, nodes, 0, callback); }
/// <summary> /// new /// </summary> /// <param name="zk"></param> /// <param name="path"></param> /// <param name="data"></param> /// <param name="acl"></param> /// <exception cref="ArgumentNullException">zk is null.</exception> public SessionNode(IZookClient zk, string path, byte[] data, Data.ACL[] acl) { if (zk == null) { throw new ArgumentNullException("zk"); } this._zk = zk; this._zk.KeeperStateChanged += new KeeperStateChangedHandler(this.KeeperStateChanged); this._nodeInfo = new NodeInfo(path, data, acl, Data.CreateModes.Ephemeral); this.CreateNode(); }
/// <summary> /// new /// </summary> /// <param name="zk"></param> /// <param name="path"></param> /// <param name="callback"></param> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">callback is null.</exception> public ChildrenWatcher(IZookClient zk, string path, Action<string[]> callback) { if (zk == null) throw new ArgumentNullException("zk"); if (callback == null) throw new ArgumentNullException("callback"); this._zk = zk; this._path = path; this._callback = callback; this._watcher = new WatcherAction(_ => this.ListChildren()); this._zk.KeeperStateChanged += this.KeeperStateChanged; this.ListChildren(); }
/// <summary> /// try create nodes /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <returns></returns> static public Task TryCreate(IZookClient zk, NodeInfo[] nodes) { if (zk == null) { throw new ArgumentNullException("zk"); } if (nodes == null || nodes.Length == 0) { throw new ArgumentNullException("nodes"); } var source = new TaskCompletionSource <bool>(); TryCreate(zk, nodes, 0, source); return(source.Task); }
/// <summary> /// 批量创建一组节点 /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="index"></param> /// <param name="callback">当所有节点创建完毕时的回调</param> static private void TryEnsureCreate(IZookClient zk, NodeInfo[] nodes, int index, Action callback) { if (index >= nodes.Length) { if (callback != null) callback(); return; } var currNode = nodes[index]; zk.Create(currNode.Path, currNode.Data, currNode.ACL, currNode.CreateMode).ContinueWith(c => { if (c.IsFaulted) { var kex = c.Exception.InnerException as KeeperException; if (kex == null || kex.Error != Data.ZoookError.NODEEXISTS) { TaskEx.Delay(new Random().Next(1000, 3000), () => TryEnsureCreate(zk, nodes, index, callback)); return; } } TryEnsureCreate(zk, nodes, index + 1, callback); }); }
/// <summary> /// new /// </summary> /// <param name="zk"></param> /// <param name="path"></param> /// <param name="callback"></param> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">callback is null.</exception> public ChildrenWatcher(IZookClient zk, string path, Action <string[]> callback) { if (zk == null) { throw new ArgumentNullException("zk"); } if (callback == null) { throw new ArgumentNullException("callback"); } this._zk = zk; this._path = path; this._callback = callback; this._watcher = new WatcherAction(_ => this.ListChildren()); this._zk.KeeperStateChanged += this.KeeperStateChanged; this.ListChildren(); }
/// <summary> /// try create node /// </summary> /// <param name="zk"></param> /// <param name="node"></param> /// <returns></returns> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">node is null.</exception> static public Task TryCreate(IZookClient zk, NodeInfo node) { if (zk == null) { throw new ArgumentNullException("zk"); } if (node == null) { throw new ArgumentNullException("node"); } return(zk.Create(node.Path, node.Data, node.ACL, node.CreateMode).ContinueWith(c => { var ex = c.Exception.InnerException as KeeperException; if (ex != null && ex.Error == Data.ZoookError.NODEEXISTS) { return; } throw c.Exception.InnerException; }, TaskContinuationOptions.OnlyOnFaulted)); }
/// <summary> /// try create nodes /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="index"></param> /// <param name="source"></param> static private void TryCreate(IZookClient zk, NodeInfo[] nodes, int index, TaskCompletionSource<bool> source) { if (index >= nodes.Length) { source.TrySetResult(true); return; } var node = nodes[index]; zk.Create(node.Path, node.Data, node.ACL, node.CreateMode).ContinueWith(c => { if (c.IsFaulted) { var ex = c.Exception.InnerException as KeeperException; if (ex == null || ex.Error != Data.ZoookError.NODEEXISTS) { source.TrySetException(c.Exception.InnerException); return; } } TryCreate(zk, nodes, index + 1, source); }); }
/// <summary> /// new /// </summary> /// <param name="port"></param> /// <param name="serviceType"></param> /// <param name="zkConfigPath"></param> /// <param name="zkConfigName"></param> /// <param name="zNode"></param> /// <param name="owner"></param> public ZookeeperRegistry(int port, string serviceType, string zkConfigPath, string zkConfigName, string zNode, string owner) { if (string.IsNullOrEmpty(serviceType)) { throw new ArgumentNullException("serviceType"); } if (string.IsNullOrEmpty(zkConfigPath)) { throw new ArgumentNullException("zkConfigPath"); } if (string.IsNullOrEmpty(zkConfigName)) { throw new ArgumentNullException("zkConfigName"); } if (string.IsNullOrEmpty(zNode)) { throw new ArgumentNullException("zNode"); } this._zk = ZookClientPool.Get(zkConfigPath, "zookeeper", zkConfigName); this.RegisterZNode(new NodeInfo[] { new NodeInfo(string.Concat("/", zNode), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent), new NodeInfo(string.Concat("/", zNode, "/providers"), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent) }); this._sessionNode = new SessionNode(this._zk, string.Concat("/", zNode, "/providers/", Uri.EscapeDataString(string.Format( @"thrift2://{0}:{1}/{2}?anyhost=true&application={3}&dispatcher=message&dubbo=2.5.1& interface={2}&loadbalance=roundrobin&methods={7}&owner={4}&pid={5}&revision=0.0.2-SNAPSHOT& side=provider&threads=100×tamp={6}", IPUtility.GetLocalIntranetIP().ToString(), port.ToString(), zNode, Process.GetCurrentProcess().ProcessName, owner ?? "", Process.GetCurrentProcess().Id.ToString(), Date.ToMillisecondsSinceEpoch(DateTime.UtcNow).ToString(), string.Join(",", Type.GetType(serviceType).GetInterfaces()[0].GetMethods().Select(c => c.Name).ToArray())))), null, IDs.OPEN_ACL_UNSAFE); }
/// <summary> /// try create nodes /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="index"></param> /// <param name="source"></param> static private void TryCreate(IZookClient zk, NodeInfo[] nodes, int index, TaskCompletionSource <bool> source) { if (index >= nodes.Length) { source.TrySetResult(true); return; } var node = nodes[index]; zk.Create(node.Path, node.Data, node.ACL, node.CreateMode).ContinueWith(c => { if (c.IsFaulted) { var ex = c.Exception.InnerException as KeeperException; if (ex == null || ex.Error != Data.ZoookError.NODEEXISTS) { source.TrySetException(c.Exception.InnerException); return; } } TryCreate(zk, nodes, index + 1, source); }); }
/// <summary> /// new /// </summary> /// <param name="serviceType"></param> /// <param name="zkConfigPath"></param> /// <param name="zkConfigName"></param> /// <param name="zNode"></param> /// <param name="callback"></param> public ZoomkeeperDiscovery(string serviceType, string zkConfigPath, string zkConfigName, string zNode, Action<IPEndPoint[]> callback) { if (string.IsNullOrEmpty(serviceType)) throw new ArgumentNullException("serviceType"); if (string.IsNullOrEmpty(zkConfigPath)) throw new ArgumentNullException("zkConfigPath"); if (string.IsNullOrEmpty(zkConfigName)) throw new ArgumentNullException("zkConfigName"); if (string.IsNullOrEmpty(zNode)) throw new ArgumentNullException("zNode"); if (callback == null) throw new ArgumentNullException("callback"); this._callback = callback; this._zk = ZookClientPool.Get(zkConfigPath, "zookeeper", zkConfigName); this.RegisterZNode(new NodeInfo[] { new NodeInfo(string.Concat("/", zNode), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent), new NodeInfo(string.Concat("/", zNode, "/consumers"), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent) }); this._sessionNode = new SessionNode(this._zk, string.Concat("/", zNode, "/consumers/", Uri.EscapeDataString(string.Format( @"consumer://{0}/{1}?application={2}&category=consumers&check=false&dubbo=2.5.1& interface={1}&methods={6}&owner={3}&pid={4}&revision=0.0.2-SNAPSHOT& side=consumer×tamp={5}", IPUtility.GetLocalIntranetIP().ToString(), zNode, Process.GetCurrentProcess().ProcessName, string.Empty, Process.GetCurrentProcess().Id.ToString(), Date.ToMillisecondsSinceEpoch(DateTime.UtcNow).ToString(), string.Join(",", Type.GetType(serviceType).GetInterfaces()[0].GetMethods().Select(c => c.Name).ToArray())))), null, IDs.OPEN_ACL_UNSAFE); this._watcher = new ChildrenWatcher(this._zk, string.Concat("/", zNode, "/providers"), arrNodes => { this._callback(arrNodes.Select(c => { var objUri = new Uri(Uri.UnescapeDataString(c)); return new IPEndPoint(IPAddress.Parse(objUri.Host), objUri.Port); }).ToArray()); //lock (this._lockObj) //{ // var arrExists = this._thrift.GetAllRegisteredEndPoint().Select(c => c.Key).Distinct().ToArray(); // var arrCurr = arrNodes.Select(node => // { // var strUrl = Uri.UnescapeDataString(node); // strUrl = strUrl.Substring(strUrl.IndexOf(":") + 3); // return strUrl.Substring(0, strUrl.IndexOf("/")); // }).ToArray(); // var set = new HashSet<string>(arrExists); // set.ExceptWith(arrCurr); // if (set.Count > 0) // { // foreach (var child in set) // this._thrift.UnRegisterEndPoint(child); // } // set = new HashSet<string>(arrCurr); // set.ExceptWith(arrExists); // if (set.Count > 0) // { // foreach (var child in set) // { // var i = child.IndexOf(":"); // var endpoint = new IPEndPoint(IPAddress.Parse(child.Substring(0, i)), int.Parse(child.Substring(i + 1))); // this._thrift.TryRegisterEndPoint(child, new EndPoint[] { endpoint }); // } // } //} }); }
/// <summary> /// new /// </summary> /// <param name="serviceType"></param> /// <param name="zkConfigPath"></param> /// <param name="zkConfigName"></param> /// <param name="zNode"></param> /// <param name="callback"></param> public ZoomkeeperDiscovery(string serviceType, string zkConfigPath, string zkConfigName, string zNode, Action <IPEndPoint[]> callback) { if (string.IsNullOrEmpty(serviceType)) { throw new ArgumentNullException("serviceType"); } if (string.IsNullOrEmpty(zkConfigPath)) { throw new ArgumentNullException("zkConfigPath"); } if (string.IsNullOrEmpty(zkConfigName)) { throw new ArgumentNullException("zkConfigName"); } if (string.IsNullOrEmpty(zNode)) { throw new ArgumentNullException("zNode"); } if (callback == null) { throw new ArgumentNullException("callback"); } this._callback = callback; this._zk = ZookClientPool.Get(zkConfigPath, "zookeeper", zkConfigName); this.RegisterZNode(new NodeInfo[] { new NodeInfo(string.Concat("/", zNode), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent), new NodeInfo(string.Concat("/", zNode, "/consumers"), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent) }); this._sessionNode = new SessionNode(this._zk, string.Concat("/", zNode, "/consumers/", Uri.EscapeDataString(string.Format( @"consumer://{0}/{1}?application={2}&category=consumers&check=false&dubbo=2.5.1& interface={1}&methods={6}&owner={3}&pid={4}&revision=0.0.2-SNAPSHOT& side=consumer×tamp={5}", IPUtility.GetLocalIntranetIP().ToString(), zNode, Process.GetCurrentProcess().ProcessName, string.Empty, Process.GetCurrentProcess().Id.ToString(), Date.ToMillisecondsSinceEpoch(DateTime.UtcNow).ToString(), string.Join(",", Type.GetType(serviceType).GetInterfaces()[0].GetMethods().Select(c => c.Name).ToArray())))), null, IDs.OPEN_ACL_UNSAFE); this._watcher = new ChildrenWatcher(this._zk, string.Concat("/", zNode, "/providers"), arrNodes => { this._callback(arrNodes.Select(c => { var objUri = new Uri(Uri.UnescapeDataString(c)); return(new IPEndPoint(IPAddress.Parse(objUri.Host), objUri.Port)); }).ToArray()); //lock (this._lockObj) //{ // var arrExists = this._thrift.GetAllRegisteredEndPoint().Select(c => c.Key).Distinct().ToArray(); // var arrCurr = arrNodes.Select(node => // { // var strUrl = Uri.UnescapeDataString(node); // strUrl = strUrl.Substring(strUrl.IndexOf(":") + 3); // return strUrl.Substring(0, strUrl.IndexOf("/")); // }).ToArray(); // var set = new HashSet<string>(arrExists); // set.ExceptWith(arrCurr); // if (set.Count > 0) // { // foreach (var child in set) // this._thrift.UnRegisterEndPoint(child); // } // set = new HashSet<string>(arrCurr); // set.ExceptWith(arrExists); // if (set.Count > 0) // { // foreach (var child in set) // { // var i = child.IndexOf(":"); // var endpoint = new IPEndPoint(IPAddress.Parse(child.Substring(0, i)), int.Parse(child.Substring(i + 1))); // this._thrift.TryRegisterEndPoint(child, new EndPoint[] { endpoint }); // } // } //} }); }
/// <summary> /// The Jones client constructor /// </summary> /// <param name="service">Service Name</param> /// <param name="hostname">Hostname</param> /// <param name="zkclient">Zookeeper Client connection object</param> /// <param name="callback">Callback function for any changes to the config tree</param> public SimpleJonesClient(string service, string hostname = null, IZookClient zkclient = null, Action <Dictionary <string, string> > callback = null) { // initialize the hostname if (String.IsNullOrEmpty(hostname)) { // get FDQN // http://stackoverflow.com/questions/804700/how-to-find-fqdn-of-local-machine-in-c-net // http://support.microsoft.com/kb/303902 HostName = System.Net.Dns.GetHostEntry("LocalHost").HostName.ToLower(); int idx = HostName.IndexOf("."); if (idx > 0) { HostName = HostName.Substring(0, idx); } } if (zkclient != null) { _zkclient = zkclient; } // initialize the dictionary to hold the configurations Config = new Dictionary <string, string>(); // set the service name ServiceName = service; // this is our callback for Config View ZNode changes, to refresh our // this.Config ConfigViewNodeChangeWatcher = new WatcherWrapper(e => { _zkclient.GetData(e.Path, ConfigViewNodeChangeWatcher).ContinueWith(d => { string conf_data = Encoding.UTF8.GetString(d.Result.Data); Config = DeserializeNodeMap(conf_data); if (callback != null) { callback.Invoke(Config); } }); }); NodeMapPath = String.Format(@"/services/{0}/nodemaps", ServiceName); #region get the current Config from the view string current_conf_path = ""; var tnm = _zkclient.GetData(NodeMapPath, false).ContinueWith(c => { string conf_path_json = Encoding.UTF8.GetString(c.Result.Data); try { current_conf_path = DeserializeNodeMap(conf_path_json)[HostName]; } catch (Exception) { // fail-safe default configs when there's no machine-specific config is found current_conf_path = String.Format(@"/services/{0}/conf", ServiceName); } var td = _zkclient.GetData(current_conf_path, ConfigViewNodeChangeWatcher).ContinueWith(d => { // this part is important so this.Config will not be empty on constructor completion! string conf_data = Encoding.UTF8.GetString(d.Result.Data); Config = DeserializeNodeMap(conf_data); }); td.Wait(); // synchronous wait }); tnm.Wait(); // synchronous wait #endregion }
/// <summary> /// The Jones client constructor /// </summary> /// <param name="service">Service Name</param> /// <param name="hostname">Hostname</param> /// <param name="zkclient">Zookeeper Client connection object</param> /// <param name="callback">Callback function for any changes to the config tree</param> public SimpleJonesClient(string service, string hostname = null, IZookClient zkclient = null, Action<Dictionary<string, string>> callback = null) { // initialize the hostname if (String.IsNullOrEmpty(hostname)) { // get FDQN // http://stackoverflow.com/questions/804700/how-to-find-fqdn-of-local-machine-in-c-net // http://support.microsoft.com/kb/303902 HostName = System.Net.Dns.GetHostEntry("LocalHost").HostName.ToLower(); int idx = HostName.IndexOf("."); if (idx > 0) { HostName = HostName.Substring(0, idx); } } if (zkclient != null) { _zkclient = zkclient; } // initialize the dictionary to hold the configurations Config = new Dictionary<string, string>(); // set the service name ServiceName = service; // this is our callback for Config View ZNode changes, to refresh our // this.Config ConfigViewNodeChangeWatcher = new WatcherWrapper(e => { _zkclient.GetData(e.Path, ConfigViewNodeChangeWatcher).ContinueWith(d => { string conf_data = Encoding.UTF8.GetString(d.Result.Data); Config = DeserializeNodeMap(conf_data); if (callback != null) { callback.Invoke(Config); } }); }); NodeMapPath = String.Format(@"/services/{0}/nodemaps", ServiceName); #region get the current Config from the view string current_conf_path = ""; var tnm = _zkclient.GetData(NodeMapPath, false).ContinueWith(c => { string conf_path_json = Encoding.UTF8.GetString(c.Result.Data); try { current_conf_path = DeserializeNodeMap(conf_path_json)[HostName]; } catch (Exception) { // fail-safe default configs when there's no machine-specific config is found current_conf_path = String.Format(@"/services/{0}/conf", ServiceName); } var td = _zkclient.GetData(current_conf_path, ConfigViewNodeChangeWatcher).ContinueWith(d => { // this part is important so this.Config will not be empty on constructor completion! string conf_data = Encoding.UTF8.GetString(d.Result.Data); Config = DeserializeNodeMap(conf_data); }); td.Wait(); // synchronous wait }); tnm.Wait(); // synchronous wait #endregion }
/// <summary> /// 批量创建一组节点 /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="callback">当所有节点创建完毕时的回调</param> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">nodes is null or empty.</exception> static public void TryEnsureCreate(IZookClient zk, NodeInfo[] nodes, Action callback) { if (zk == null) throw new ArgumentNullException("zk"); if (nodes == null || nodes.Length == 0) throw new ArgumentNullException("nodes"); TryEnsureCreate(zk, nodes, 0, callback); }
/// <summary> /// 创建节点 /// </summary> /// <param name="zk"></param> /// <param name="node"></param> /// <param name="callback"></param> static public void TryEnsureCreate(IZookClient zk, NodeInfo node, Action callback) { TryEnsureCreate(zk, new NodeInfo[] { node }, callback); }