/// <summary>
        /// Check for timeout from timeout queue thread.
        /// </summary>
        public bool CheckTimeout()
        {
            if (state != IN_PROGRESS)
            {
                return(false);
            }

            Stopwatch watch = totalWatch;

            if (watch != null && watch.ElapsedMilliseconds >= totalTimeout)
            {
                // Total timeout has occurred.
                if (Interlocked.CompareExchange(ref state, FAIL_TOTAL_TIMEOUT, IN_PROGRESS) == IN_PROGRESS)
                {
                    // Close connection. This will result in a socket error in the async callback thread.
                    if (conn != null)
                    {
                        node.CloseAsyncConnOnError(conn);
                    }

                    // Notify user immediately in this timeout thread.
                    // Transaction thread will cleanup eventArgs.
                    NotifyFailure(new AerospikeException.Timeout(policy, true));
                }
                return(false);                 // Do not put back on timeout queue.
            }

            watch = socketWatch;

            if (watch != null && watch.ElapsedMilliseconds >= socketTimeout)
            {
                if (eventReceived)
                {
                    // Event(s) received within socket timeout period.
                    eventReceived = false;
                    socketWatch   = Stopwatch.StartNew();
                    return(true);
                }

                // Socket timeout has occurred.
                if (Interlocked.CompareExchange(ref state, FAIL_SOCKET_TIMEOUT, IN_PROGRESS) == IN_PROGRESS)
                {
                    // User will be notified in transaction thread and this timeout thread.
                    // Close connection. This will result in a socket error in the async callback thread
                    // and a possible retry.
                    if (conn != null)
                    {
                        node.CloseAsyncConnOnError(conn);
                    }
                }
                return(false);       // Do not put back on timeout queue.
            }
            return(true);            // Timeout not reached.
        }
        public bool CheckTimeout()
        {
            if (state != 0)
            {
                return(false);                // Do not put back on timeout queue.
            }

            long elapsed = watch.ElapsedMilliseconds;

            if (elapsed < cluster.connectionTimeout)
            {
                return(true);                // Timeout not reached.
            }

            if (Interlocked.CompareExchange(ref state, 1, 0) == 0)
            {
                // Close connection. This will result in a socket error.
                if (conn != null)
                {
                    node.CloseAsyncConnOnError(conn);
                }
            }
            return(false);            // Do not put back on timeout queue.
        }
        public AsyncConnector(
            AsyncCluster cluster,
            AsyncNode node,
            ConnectorListener listener,
            SocketAsyncEventArgs args,
            byte[] buffer
            )
        {
            this.cluster             = cluster;
            this.node                = node;
            this.listener            = listener;
            this.eventArgs           = args;
            this.eventArgs.UserToken = this;
            this.dataBuffer          = buffer;

            this.watch = Stopwatch.StartNew();
            AsyncTimeoutQueue.Instance.Add(this, cluster.connectionTimeout);

            node.IncrAsyncConnTotal();
            conn = new AsyncConnection(node.address, node);

            try
            {
                eventArgs.SetBuffer(dataBuffer, 0, 0);

                if (!conn.ConnectAsync(eventArgs))
                {
                    ConnectionCreated();
                }
            }
            catch (Exception)
            {
                node.CloseAsyncConnOnError(conn);
                throw;
            }
        }