예제 #1
0
        /// <summary>
        /// Return the stat of the node of the given path. Return null if no such a
        /// node exists.
        ///
        /// If the watch is non-null and the call is successful (no exception is thrown),
        /// a watch will be left on the node with the given path. The watch will be
        /// triggered by a successful operation that creates/delete the node or sets
        /// the data on the node.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="watcher">The watcher.</param>
        /// <returns>the stat of the node of the given path; return null if no such a node exists.</returns>
        public Stat Exists(string path, IWatcher watcher)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            // the watch contains the un-chroot path
            WatchRegistration wcb = null;

            if (watcher != null)
            {
                wcb = new ExistsWatchRegistration(watchManager, watcher, clientPath);
            }

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.Exists;
            ExistsRequest   request  = new ExistsRequest(serverPath, watcher != null);
            SetDataResponse response = new SetDataResponse();
            ReplyHeader     r        = cnxn.SubmitRequest(h, request, response, wcb);

            if (r.Err != 0)
            {
                if (r.Err == (int)KeeperException.Code.NONODE)
                {
                    return(null);
                }
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }

            return(response.Stat.Czxid == -1 ? null : response.Stat);
        }
예제 #2
0
        /// <summary>
        /// Create a node with the given path. The node data will be the given data,
        /// and node acl will be the given acl.
        ///
        /// The flags argument specifies whether the created node will be ephemeral
        /// or not.
        ///
        /// An ephemeral node will be removed by the ZooKeeper automatically when the
        /// session associated with the creation of the node expires.
        ///
        /// The flags argument can also specify to create a sequential node. The
        /// actual path name of a sequential node will be the given path plus a
        /// suffix "i" where i is the current sequential number of the node. The sequence
        /// number is always fixed length of 10 digits, 0 padded. Once
        /// such a node is created, the sequential number will be incremented by one.
        ///
        /// If a node with the same actual path already exists in the ZooKeeper, a
        /// KeeperException with error code KeeperException.NodeExists will be
        /// thrown. Note that since a different actual path is used for each
        /// invocation of creating sequential node with the same path argument, the
        /// call will never throw "file exists" KeeperException.
        ///
        /// If the parent node does not exist in the ZooKeeper, a KeeperException
        /// with error code KeeperException.NoNode will be thrown.
        ///
        /// An ephemeral node cannot have children. If the parent node of the given
        /// path is ephemeral, a KeeperException with error code
        /// KeeperException.NoChildrenForEphemerals will be thrown.
        ///
        /// This operation, if successful, will trigger all the watches left on the
        /// node of the given path by exists and getData API calls, and the watches
        /// left on the parent node by getChildren API calls.
        ///
        /// If a node is created successfully, the ZooKeeper server will trigger the
        /// watches on the path left by exists calls, and the watches on the parent
        /// of the node by getChildren calls.
        ///
        /// The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
        /// Arrays larger than this will cause a KeeperExecption to be thrown.
        /// </summary>
        /// <param name="path">The path for the node.</param>
        /// <param name="data">The data for the node.</param>
        /// <param name="acl">The acl for the node.</param>
        /// <param name="createMode">specifying whether the node to be created is ephemeral and/or sequential.</param>
        /// <returns></returns>
        public string Create(string path, byte[] data, IEnumerable <ACL> acl, CreateMode createMode)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath, createMode.Sequential);
            if (acl != null && acl.Count() == 0)
            {
                throw new KeeperException.InvalidACLException();
            }

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.Create;
            CreateRequest  request  = new CreateRequest(serverPath, data, acl, createMode.Flag);
            CreateResponse response = new CreateResponse();
            ReplyHeader    r        = cnxn.SubmitRequest(h, request, response, null);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            return(cnxn.ChrootPath == null ? response.Path : response.Path.Substring(cnxn.ChrootPath.Length));
        }
예제 #3
0
        /**
         * All non-specific keeper exceptions should be constructed via
         * this factory method in order to guarantee consistency in error
         * codes and such.  If you know the error code, then you should
         * construct the special purpose exception directly.  That will
         * allow you to have the most specific possible declarations of
         * what exceptions might actually be thrown.
         *
         * @param code The error code.
         * @param path The ZooKeeper path being operated on.
         * @return The specialized exception, presumably to be thrown by
         *  the caller.
         */
        public static KeeperException Create(Code code, string path)
        {
            KeeperException r = Create(code);

            r.path = path;
            return(r);
        }
예제 #4
0
        //added by Yang Li at Feb.29th, 2016
        public byte[] GetRemark(string path, IWatcher watcher, Stat stat)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            // the watch contains the un-chroot path
            WatchRegistration wcb = null;

            if (watcher != null)
            {
                wcb = new DataWatchRegistration(watchManager, watcher, clientPath);
            }

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

#warning code here
            //h.Type = (int)OpCode.GetRemark;
            h.Type = (int)OpCode.GetData;
            GetRemarkRequest  request  = new GetRemarkRequest(serverPath, watcher != null);
            GetRemarkResponse response = new GetRemarkResponse();
            ReplyHeader       r        = cnxn.SubmitRequest(h, request, response, wcb);
            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            if (stat != null)
            {
                DataTree.CopyStat(response.Stat, stat);
            }
            return(response.Remark);
        }
예제 #5
0
        private async Task <IEnumerable <string> > GetChildrenAsyncInternal(string path, IWatcher watcher, Stat stat, bool sync)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            // the watch contains the un-chroot path
            WatchRegistration wcb = null;

            if (watcher != null)
            {
                wcb = new ChildWatchRegistration(watchManager, watcher, clientPath);
            }

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.GetChildren2;
            GetChildren2Request  request  = new GetChildren2Request(serverPath, watcher != null);
            GetChildren2Response response = new GetChildren2Response();
            ReplyHeader          r        = sync ? cnxn.SubmitRequest(h, request, response, wcb)
                : await cnxn.SubmitRequestAsync(h, request, response, wcb).ConfigureAwait(false);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            if (stat != null)
            {
                DataTree.CopyStat(response.Stat, stat);
            }
            return(response.Children);
        }
예제 #6
0
        /// <summary>
        /// Set the data for the node of the given path if such a node exists and the
        /// given version matches the version of the node (if the given version is
        /// -1, it matches any node's versions). Return the stat of the node.
        ///
        /// This operation, if successful, will trigger all the watches on the node
        /// of the given path left by getData calls.
        ///
        /// A KeeperException with error code KeeperException.NoNode will be thrown
        /// if no node with the given path exists.
        ///
        /// A KeeperException with error code KeeperException.BadVersion will be
        /// thrown if the given version does not match the node's version.
        ///
        /// The maximum allowable size of the data array is 1 MB (1,048,576 bytes).
        /// Arrays larger than this will cause a KeeperExecption to be thrown.
        /// @param path
        ///                the path of the node
        /// @param data
        ///                the data to set
        /// @param version
        ///                the expected matching version
        /// @return the state of the node
        /// @throws InterruptedException If the server transaction is interrupted.
        /// @throws KeeperException If the server signals an error with a non-zero error code.
        /// @throws IllegalArgumentException if an invalid path is specified
        /// </summary>
        public Stat SetData(string path, byte[] data, int version)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.SetData;
            SetDataRequest request = new SetDataRequest();

            request.Path    = serverPath;
            request.Data    = data;
            request.Version = version;
            SetDataResponse response = new SetDataResponse();
            ReplyHeader     r        = cnxn.SubmitRequest(h, request, response, null);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            return(response.Stat);
        }
예제 #7
0
        private async Task <Stat> SetACLAsyncInternal(string path, IEnumerable <ACL> acl, int version, bool sync)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);
            if (acl != null && acl.Count() == 0)
            {
                throw new KeeperException.InvalidACLException();
            }

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.SetACL;
            SetACLRequest  request  = new SetACLRequest(serverPath, acl, version);
            SetACLResponse response = new SetACLResponse();
            ReplyHeader    r        = sync ? cnxn.SubmitRequest(h, request, response, null)
                : await cnxn.SubmitRequestAsync(h, request, response, null).ConfigureAwait(false);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            return(response.Stat);
        }
예제 #8
0
        /// <summary>
        /// Set the ACL for the node of the given path if such a node exists and the
        /// given version matches the version of the node. Return the stat of the
        /// node.
        ///
        /// A KeeperException with error code KeeperException.NoNode will be thrown
        /// if no node with the given path exists.
        ///
        /// A KeeperException with error code KeeperException.BadVersion will be
        /// thrown if the given version does not match the node's version.
        /// @param path
        /// @param acl
        /// @param version
        /// @return the stat of the node.
        /// @throws InterruptedException If the server transaction is interrupted.
        /// @throws KeeperException If the server signals an error with a non-zero error code.
        /// @throws org.apache.zookeeper.KeeperException.InvalidACLException If the acl is invalide.
        /// @throws IllegalArgumentException if an invalid path is specified
        /// </summary>
        public Stat SetACL(string path, IEnumerable <ACL> acl, int version)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);
            if (acl != null && acl.Count() == 0)
            {
                throw new KeeperException.InvalidACLException();
            }

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.SetACL;
            SetACLRequest  request  = new SetACLRequest(serverPath, acl, version);
            SetACLResponse response = new SetACLResponse();
            ReplyHeader    r        = cnxn.SubmitRequest(h, request, response, null);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            return(response.Stat);
        }
예제 #9
0
        /// <summary>
        /// Return the list of the children of the node of the given path.
        ///
        /// If the watch is non-null and the call is successful (no exception is thrown),
        /// a watch will be left on the node with the given path. The watch willbe
        /// triggered by a successful operation that deletes the node of the given
        /// path or creates/delete a child under the node.
        ///
        /// The list of children returned is not sorted and no guarantee is provided
        /// as to its natural or lexical order.
        ///
        /// A KeeperException with error code KeeperException.NoNode will be thrown
        /// if no node with the given path exists.
        /// @param path
        /// @param watcher explicit watcher
        /// @return an unordered array of children of the node with the given path
        /// @throws InterruptedException If the server transaction is interrupted.
        /// @throws KeeperException If the server signals an error with a non-zero error code.
        /// @throws IllegalArgumentException if an invalid path is specified
        /// </summary>
        public IEnumerable <string> GetChildren(string path, IWatcher watcher)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            // the watch contains the un-chroot path
            WatchRegistration wcb = null;

            if (watcher != null)
            {
                wcb = new ChildWatchRegistration(watchManager, watcher, clientPath);
            }

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.GetChildren2;
            GetChildren2Request  request  = new GetChildren2Request(serverPath, watcher != null);
            GetChildren2Response response = new GetChildren2Response();
            ReplyHeader          r        = cnxn.SubmitRequest(h, request, response, wcb);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            return(response.Children);
        }
예제 #10
0
        /// <summary>
        /// Delete the node with the given path. The call will succeed if such a node
        /// exists, and the given version matches the node's version (if the given
        /// version is -1, it matches any node's versions).
        ///
        /// A KeeperException with error code KeeperException.NoNode will be thrown
        /// if the nodes does not exist.
        ///
        /// A KeeperException with error code KeeperException.BadVersion will be
        /// thrown if the given version does not match the node's version.
        ///
        /// A KeeperException with error code KeeperException.NotEmpty will be thrown
        /// if the node has children.
        ///
        /// This operation, if successful, will trigger all the watches on the node
        /// of the given path left by exists API calls, and the watches on the parent
        /// node left by getChildren API calls.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="version">The version.</param>
        public void Delete(string path, int version)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            string serverPath;

            // maintain semantics even in chroot case
            // specifically - root cannot be deleted
            // I think this makes sense even in chroot case.
            if (clientPath.Equals(PathUtils.PathSeparator))
            {
                // a bit of a hack, but delete(/) will never succeed and ensures
                // that the same semantics are maintained
                serverPath = clientPath;
            }
            else
            {
                serverPath = PrependChroot(clientPath);
            }

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.Delete;
            DeleteRequest request = new DeleteRequest(serverPath, version);
            ReplyHeader   r       = cnxn.SubmitRequest(h, request, null, null);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
        }
예제 #11
0
 public static ZkException Create(KeeperException e)
 {
     switch (e.ErrorCode)
     {
         case KeeperException.Code.NONODE:
             return new ZkNoNodeException(e.Message, e);
         case KeeperException.Code.BADVERSION:
             return new ZkBadVersionException(e.Message, e);
         case KeeperException.Code.NODEEXISTS:
             return new ZkNodeExistsException(e.Message, e);
         default:
             return new ZkException(e.Message, e);
     }
 }
        public void ProcessResult(KeeperException.Code rc, String path, Object ctx, Stat stat)
        {
            bool exists;
            switch (rc)
            {
                case KeeperException.Code.OK:
                    exists = true;
                    break;
                case KeeperException.Code.NONODE:
                    exists = false;
                    break;
                case KeeperException.Code.SESSIONEXPIRED:
                case KeeperException.Code.NOAUTH:
                    Dead = true;
                    _listener.Closing(rc);
                    return;
                default:
                    // Retry errors
                    _zk.Exists(_znode, true);
                    return;
            }

            byte[] b = null;
            if (exists)
            {
                try
                {
                    b = _zk.GetData(_znode, false, null);
                }
                catch (KeeperException e)
                {
                    // We don't need to worry about recovering now. The watch
                    // callbacks will kick off any exception handling
                    //TODO
                }
                catch (Exception e)
                {
                    return;
                }
            }
            if ((b == null && b != _prevData)
                || (b != null && !Equals(_prevData, b)))
            {
                _listener.Exists(b);
                _prevData = b;
            }
        }
예제 #13
0
        private async Task <Stat> SetDataAsyncInternal(string path, byte[] data, int version, bool sync)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.SetData;
            SetDataRequest  request  = new SetDataRequest(serverPath, data, version);
            SetDataResponse response = new SetDataResponse();
            ReplyHeader     r        = cnxn.SubmitRequest(h, request, response, null);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            return(response.Stat);
        }
예제 #14
0
        /// <summary>
        /// Return the ACL and stat of the node of the given path.
        ///
        /// A KeeperException with error code KeeperException.NoNode will be thrown
        /// if no node with the given path exists.
        /// @param path
        ///                the given path for the node
        /// @param stat
        ///                the stat of the node will be copied to this parameter.
        /// @return the ACL array of the given node.
        /// @throws InterruptedException If the server transaction is interrupted.
        /// @throws KeeperException If the server signals an error with a non-zero error code.
        /// @throws IllegalArgumentException if an invalid path is specified
        /// </summary>
        public IEnumerable <ACL> GetACL(string path, Stat stat)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.GetACL;
            GetACLRequest  request  = new GetACLRequest(serverPath);
            GetACLResponse response = new GetACLResponse();
            ReplyHeader    r        = cnxn.SubmitRequest(h, request, response, null);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            DataTree.CopyStat(response.Stat, stat);
            return(response.Acl);
        }
예제 #15
0
        private async Task <IEnumerable <ACL> > GetACLAsyncInternal(string path, Stat stat, bool sync)
        {
            string clientPath = path;

            PathUtils.ValidatePath(clientPath);

            string serverPath = PrependChroot(clientPath);

            RequestHeader h = new RequestHeader();

            h.Type = (int)OpCode.GetACL;
            GetACLRequest  request  = new GetACLRequest(serverPath);
            GetACLResponse response = new GetACLResponse();
            ReplyHeader    r        = sync ? cnxn.SubmitRequest(h, request, response, null)
                : await cnxn.SubmitRequestAsync(h, request, response, null).ConfigureAwait(false);

            if (r.Err != 0)
            {
                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err), clientPath);
            }
            DataTree.CopyStat(response.Stat, stat);
            return(response.Acl);
        }
예제 #16
0
        private void PrimeConnection()
        {
            LOG.InfoFormat("Socket connection established to {0}, initiating session", client.Client.RemoteEndPoint);
            ConnectRequest conReq    = new ConnectRequest(0, lastZxid, Convert.ToInt32(conn.SessionTimeout.TotalMilliseconds), conn.SessionId, conn.SessionPassword);
            Packet         conPacket = new Packet(null, null, conReq, null, null, null, null, null);

            if (conn.saslClient != null)
            {
                lock (outgoingQueue)
                {
                    // SASL negociation is synchronous, and must complete before we send the (non-SASL) auth data and
                    // watches.  We explicitly drive the send/receive as the queue processing loop is not active yet.

                    // First, push the ConnectRequest down the pipe.
                    DoSend(conPacket);
                    conPacket = null;

                    byte[] token = conn.saslClient.Start((IPEndPoint)client.Client.LocalEndPoint,
                                                         (IPEndPoint)client.Client.RemoteEndPoint);

                    try
                    {
                        bool lastPacket = false;

                        do
                        {
                            RequestHeader h = new RequestHeader();
                            ReplyHeader   r = new ReplyHeader();
                            h.Type = (int)OpCode.SASL;
                            GetSASLRequest  request  = new GetSASLRequest(token != null ? token : new byte[0]);
                            SetSASLResponse response = new SetSASLResponse();

                            Packet p = new Packet(h, r, request, response, null, null, null, null);

                            // Push the packet.
                            DoSend(p);

                            // Synchronously wait for the response.
                            if (!p.Task.Wait(conn.ConnectionTimeout))
                            {
                                throw new TimeoutException($"The request {request} timed out while waiting for a response from the server.");
                            }

                            if (r.Err != 0)
                            {
                                throw KeeperException.Create((KeeperException.Code)Enum.ToObject(typeof(KeeperException.Code), r.Err));
                            }

                            if (lastPacket)
                            {
                                break;
                            }

                            // SASL round.
                            token = conn.saslClient.EvaluateChallenge(response.Token);

                            if (conn.saslClient.IsCompleted)
                            {
                                if (conn.saslClient.HasLastPacket)
                                {
                                    lastPacket = true;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        // We must have received a 'ConnectResponse' by
                        // now, as we have waited for 1+ packets.
                        while (zooKeeper.State.IsConnected());
                    }
                    finally
                    {
                        conn.saslClient.Finish();
                    }
                }

                if (zooKeeper.State.IsConnected())
                {
                    conn.consumer.QueueEvent(new WatchedEvent(KeeperState.SaslAuthenticated, EventType.None, null));
                }
            }

            bool hasOutgoingRequests;

            lock (outgoingQueue)
            {
                if (!ClientConnection.DisableAutoWatchReset && (!zooKeeper.DataWatches.IsEmpty() || !zooKeeper.ExistWatches.IsEmpty() || !zooKeeper.ChildWatches.IsEmpty()))
                {
                    var sw = new SetWatches(lastZxid, prependChroot(zooKeeper.DataWatches), prependChroot(zooKeeper.ExistWatches), prependChroot(zooKeeper.ChildWatches));
                    var h  = new RequestHeader();
                    h.Type = (int)OpCode.SetWatches;
                    h.Xid  = -8;
                    Packet packet = new Packet(h, new ReplyHeader(), sw, null, null, null, null, null);
                    //outgoingQueue.AddFirst(packet);
                    addPacketFirst(packet);
                }

                foreach (ClientConnection.AuthData id in conn.authInfo)
                {
                    addPacketFirst(
                        new Packet(new RequestHeader(-4, (int)OpCode.Auth), null, new AuthPacket(0, id.Scheme, id.GetData()), null, null, null, null, null));
                }

                // The ConnectRequest packet has already been sent in the SASL case.
                if (conPacket != null)
                {
                    addPacketFirst(conPacket);
                    conPacket = null;
                }

                hasOutgoingRequests = !outgoingQueue.IsEmpty();
            }

            if (hasOutgoingRequests)
            {
                packetAre.Set();
            }

            if (LOG.IsDebugEnabled)
            {
                LOG.DebugFormat("Session establishment request sent on {0}", client.Client.RemoteEndPoint);
            }
        }
예제 #17
0
        private void StartConnect()
        {
            zooKeeper.State = ZooKeeper.States.CONNECTING;
            TcpClient  tempClient = null;
            WaitHandle wh         = null;

            do
            {
                if (zkEndpoints.EndPointID != -1)
                {
                    try
                    {
                        Thread.Sleep(new TimeSpan(0, 0, 0, 0, random.Next(0, 50)));
                    }
                    catch (ThreadInterruptedException e1)
                    {
                        LOG.Warn("Unexpected exception", e1);
                    }
                    if (!zkEndpoints.IsNextEndPointAvailable)
                    {
                        try
                        {
                            // Try not to spin too fast!
                            Thread.Sleep(1000);
                        }
                        catch (ThreadInterruptedException e)
                        {
                            LOG.Warn("Unexpected exception", e);
                        }
                    }
                }

                //advance through available connections;
                zkEndpoints.GetNextAvailableEndpoint();

                Cleanup(tempClient);
                LOG.InfoFormat("Opening socket connection to server {0}", zkEndpoints.CurrentEndPoint.ServerAddress);
                tempClient             = new TcpClient();
                tempClient.LingerState = new LingerOption(false, 0);
                tempClient.NoDelay     = true;

                Interlocked.Exchange(ref initialized, 0);
                IsConnectionClosedByServer = false;

                try
                {
                    IAsyncResult ar = tempClient.BeginConnect(zkEndpoints.CurrentEndPoint.ServerAddress.Address,
                                                              zkEndpoints.CurrentEndPoint.ServerAddress.Port,
                                                              null,
                                                              null);

                    wh = ar.AsyncWaitHandle;
                    if (!ar.AsyncWaitHandle.WaitOne(conn.ConnectionTimeout, false))
                    {
                        Cleanup(tempClient);
                        tempClient = null;
                        throw new TimeoutException();
                    }

                    tempClient.EndConnect(ar);

                    break;
                }
                catch (Exception ex)
                {
                    if (ex is SocketException || ex is TimeoutException)
                    {
                        Cleanup(tempClient);
                        tempClient = null;
                        zkEndpoints.CurrentEndPoint.SetAsFailure();

                        LOG.WarnFormat(string.Format("Failed to connect to {0}:{1}.",
                                                     zkEndpoints.CurrentEndPoint.ServerAddress.Address.ToString(),
                                                     zkEndpoints.CurrentEndPoint.ServerAddress.Port.ToString()));
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    wh.Close();
                }
            }while (zkEndpoints.IsNextEndPointAvailable);

            if (tempClient == null)
            {
                throw KeeperException.Create(KeeperException.Code.CONNECTIONLOSS);
            }

            Interlocked.Exchange(ref client, tempClient);
            client.GetStream().BeginRead(incomingBuffer, 0, incomingBuffer.Length, ReceiveAsynch, Tuple.Create(client, incomingBuffer));
            PrimeConnection();
        }
        private void StartConnect()
        {
            zooKeeper.State = ZooKeeper.States.CONNECTING;
            TcpClient  tempClient = null;
            WaitHandle wh         = null;

            do
            {
                if (zkEndpoints.EndPointID != -1)
                {
                    try
                    {
                        Thread.Sleep(new TimeSpan(0, 0, 0, 0, random.Next(0, 50)));
                    }
#if !NET_CORE
                    catch (ThreadInterruptedException e)
                    {
                        LOG.Error("Event thread exiting due to interruption", e);
                    }
#endif
#if NET_CORE
                    catch (Exception e)
                    {
                    }
#endif
                    if (!zkEndpoints.IsNextEndPointAvailable)
                    {
                        try
                        {
                            // Try not to spin too fast!
                            Thread.Sleep(1000);
                        }
#if !NET_CORE
                        catch (ThreadInterruptedException e)
                        {
                            LOG.Error("Event thread exiting due to interruption", e);
                        }
#endif
#if NET_CORE
                        catch (Exception e)
                        {
                        }
#endif
                    }
                }

                //advance through available connections;
                zkEndpoints.GetNextAvailableEndpoint();

                Cleanup(tempClient);
                Console.WriteLine("Opening socket connection to server {0}", zkEndpoints.CurrentEndPoint.ServerAddress);
#if !NET_CORE
                LOG.InfoFormat("Opening socket connection to server {0}", zkEndpoints.CurrentEndPoint.ServerAddress);
#endif
                tempClient             = new TcpClient();
                tempClient.LingerState = new LingerOption(false, 0);
                tempClient.NoDelay     = true;

                Interlocked.Exchange(ref initialized, 0);
                IsConnectionClosedByServer = false;

                try
                {
                    IAsyncResult ar = tempClient.BeginConnect(zkEndpoints.CurrentEndPoint.ServerAddress.Address,
                                                              zkEndpoints.CurrentEndPoint.ServerAddress.Port,
                                                              null,
                                                              null);

                    wh = ar.AsyncWaitHandle;
#if !NET_CORE
                    if (!ar.AsyncWaitHandle.WaitOne(conn.ConnectionTimeout, false))
                    {
                        Cleanup(tempClient);
                        tempClient = null;
                        throw new TimeoutException();
                    }
#else
                    if (!ar.AsyncWaitHandle.WaitOne(conn.ConnectionTimeout))
                    {
                        Cleanup(tempClient);
                        tempClient = null;
                        throw new TimeoutException();
                    }
#endif

                    //tempClient.EndConnect(ar);

                    zkEndpoints.CurrentEndPoint.SetAsSuccess();

                    break;
                }
                catch (Exception ex)
                {
                    if (ex is SocketException || ex is TimeoutException)
                    {
                        Cleanup(tempClient);
                        tempClient = null;
                        zkEndpoints.CurrentEndPoint.SetAsFailure();
#if !NET_CORE
                        LOG.WarnFormat(string.Format("Failed to connect to {0}:{1}.",
                                                     zkEndpoints.CurrentEndPoint.ServerAddress.Address.ToString(),
                                                     zkEndpoints.CurrentEndPoint.ServerAddress.Port.ToString()));
#endif
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
#if !NET_CORE
                    wh.Close();
#endif
#if NET_CORE
                    wh.Dispose();
#endif
                }
            }while (zkEndpoints.IsNextEndPointAvailable);

            if (tempClient == null)
            {
                throw KeeperException.Create(KeeperException.Code.CONNECTIONLOSS);
            }

            client = tempClient;
#if !NET_CORE
            client.GetStream().BeginRead(incomingBuffer, 0, incomingBuffer.Length, ReceiveAsynch, incomingBuffer);
#endif

#if NET_CORE
            byte[] byteData    = incomingBuffer;
            var    tokenSource = new CancellationTokenSource();
            var    token       = tokenSource.Token;
            client.GetStream().ReadAsync(incomingBuffer, 0, incomingBuffer.Length, token);
            tokenSource.Cancel();
            MyReceiveAsynch(-1, byteData);
#endif

            PrimeConnection();
        }