예제 #1
0
        private void ExecuteQuery(Cluster cluster, AdminPolicy policy)
        {
            WriteSize();
            Node       node    = cluster.GetRandomNode();
            int        timeout = (policy == null) ? 1000 : policy.timeout;
            int        status  = 0;
            Connection conn    = node.GetConnection(timeout);

            try
            {
                conn.Write(dataBuffer, dataOffset);
                status = ReadBlocks(conn);
                node.PutConnection(conn);
            }
            catch (Exception e)
            {
                // Garbage may be in socket.  Do not put back into pool.
                node.CloseConnection(conn);
                throw new AerospikeException(e);
            }

            if (status != QUERY_END && status > 0)
            {
                throw new AerospikeException(status, "Query failed.");
            }
        }
예제 #2
0
        //-------------------------------------------------------
        // Private methods.
        //-------------------------------------------------------

        /// <summary>
        /// Issue request and set results buffer. This method is used internally.
        /// The static request methods should be used instead.
        /// </summary>
        /// <param name="conn">socket connection to server node</param>
        /// <exception cref="AerospikeException">if socket send or receive fails</exception>
        private void SendCommand(Connection conn)
        {
            try
            {
                // Write size field.
                ulong size = ((ulong)offset - 8L) | (2L << 56) | (1L << 48);
                ByteUtil.LongToBytes(size, buffer, 0);

                // Write.
                conn.Write(buffer, offset);

                // Read - reuse input buffer.
                conn.ReadFully(buffer, 8);

                size   = (ulong)ByteUtil.BytesToLong(buffer, 0);
                length = (int)(size & 0xFFFFFFFFFFFFL);
                ResizeBuffer(length);
                conn.ReadFully(buffer, length);
                offset = 0;
            }
            catch (SocketException se)
            {
                throw new AerospikeException(se);
            }
        }
예제 #3
0
        private void ExecuteCommand(Cluster cluster, AdminPolicy policy)
        {
            WriteSize();
            Node       node    = cluster.GetRandomNode();
            int        timeout = (policy == null) ? 1000 : policy.timeout;
            Connection conn    = node.GetConnection(timeout);

            try
            {
                conn.Write(dataBuffer, dataOffset);
                conn.ReadFully(dataBuffer, HEADER_SIZE);
                node.PutConnection(conn);
            }
            catch (Exception)
            {
                // Garbage may be in socket.  Do not put back into pool.
                node.CloseConnection(conn);
                throw;
            }

            int result = dataBuffer[RESULT_CODE];

            if (result != 0)
            {
                throw new AerospikeException(result);
            }
        }
        public bool Authenticate(Cluster cluster, Connection conn, byte[] sessionToken)
        {
            dataOffset = 8;
            SetAuthenticate(cluster, sessionToken);
            conn.Write(dataBuffer, dataOffset);
            conn.ReadFully(dataBuffer, HEADER_SIZE);

            return(dataBuffer[RESULT_CODE] == 0);
        }
        public bool Authenticate(Cluster cluster, Connection conn, byte[] sessionToken)
        {
            dataOffset = 8;
            SetAuthenticate(cluster, sessionToken);
            conn.Write(dataBuffer, dataOffset);
            conn.ReadFully(dataBuffer, HEADER_SIZE);

            int result = dataBuffer[RESULT_CODE];

            return(result == 0 || result == ResultCode.SECURITY_NOT_ENABLED);
        }
예제 #6
0
        public void Authenticate(Connection conn, byte[] user, byte[] password)
        {
            SetAuthenticate(user, password);
            conn.Write(dataBuffer, dataOffset);
            conn.ReadFully(dataBuffer, HEADER_SIZE);

            int result = dataBuffer[RESULT_CODE];

            if (result != 0)
            {
                throw new AerospikeException(result, "Authentication failed");
            }
        }
        public void AuthenticateOld(Cluster cluster, Connection conn)
        {
            dataOffset = 8;
            WriteHeader(AUTHENTICATE, 2);
            WriteField(USER, cluster.user);
            WriteField(CREDENTIAL, cluster.passwordHash);
            WriteSize();

            conn.Write(dataBuffer, dataOffset);
            conn.ReadFully(dataBuffer, HEADER_SIZE);

            int result = dataBuffer[RESULT_CODE];

            if (result != 0)
            {
                throw new AerospikeException(result, "Authentication failed");
            }
        }
예제 #8
0
        public void ExecuteCommand()
        {
            Node node;
            AerospikeException exception = null;
            bool isClientTimeout;

            // Execute command until successful, timed out or maximum iterations have been reached.
            while (true)
            {
                try
                {
                    node = GetNode();
                }
                catch (AerospikeException ae)
                {
                    ae.Policy    = policy;
                    ae.Iteration = iteration;
                    ae.SetInDoubt(IsWrite(), commandSentCounter);
                    throw;
                }

                try
                {
                    Connection conn = node.GetConnection(socketTimeout);

                    try
                    {
                        // Set command buffer.
                        WriteBuffer();

                        // Send command.
                        conn.Write(dataBuffer, dataOffset);
                        commandSentCounter++;

                        // Parse results.
                        ParseResult(conn);

                        // Put connection back in pool.
                        node.PutConnection(conn);

                        // Command has completed successfully.  Exit method.
                        return;
                    }
                    catch (AerospikeException ae)
                    {
                        if (ae.KeepConnection())
                        {
                            // Put connection back in pool.
                            node.PutConnection(conn);
                        }
                        else
                        {
                            // Close socket to flush out possible garbage.  Do not put back in pool.
                            node.CloseConnection(conn);
                        }

                        if (ae.Result == ResultCode.TIMEOUT)
                        {
                            // Go through retry logic on server timeout.
                            exception       = new AerospikeException.Timeout(policy, false);
                            isClientTimeout = false;
                        }
                        else
                        {
                            throw;
                        }
                    }
                    catch (SocketException se)
                    {
                        // Socket errors are considered temporary anomalies.
                        // Retry after closing connection.
                        node.CloseConnection(conn);

                        if (se.SocketErrorCode == SocketError.TimedOut)
                        {
                            isClientTimeout = true;
                        }
                        else
                        {
                            exception       = new AerospikeException.Connection(se);
                            isClientTimeout = false;
                        }
                    }
                    catch (Exception)
                    {
                        // All other exceptions are considered fatal.  Do not retry.
                        // Close socket to flush out possible garbage.  Do not put back in pool.
                        node.CloseConnection(conn);
                        throw;
                    }
                }
                catch (SocketException se)
                {
                    // This exception might happen after initial connection succeeded, but
                    // user login failed with a socket error.  Retry.
                    if (se.SocketErrorCode == SocketError.TimedOut)
                    {
                        isClientTimeout = true;
                    }
                    else
                    {
                        exception       = new AerospikeException.Connection(se);
                        isClientTimeout = false;
                    }
                }
                catch (AerospikeException.Connection ce)
                {
                    // Socket connection error has occurred. Retry.
                    exception       = ce;
                    isClientTimeout = false;
                }
                catch (AerospikeException ae)
                {
                    ae.Node      = node;
                    ae.Policy    = policy;
                    ae.Iteration = iteration;
                    ae.SetInDoubt(IsWrite(), commandSentCounter);
                    throw;
                }

                // Check maxRetries.
                if (iteration > maxRetries)
                {
                    break;
                }

                if (totalTimeout > 0)
                {
                    // Check for total timeout.
                    long remaining = (long)deadline.Subtract(DateTime.UtcNow).TotalMilliseconds - policy.sleepBetweenRetries;

                    if (remaining <= 0)
                    {
                        break;
                    }

                    if (remaining < totalTimeout)
                    {
                        totalTimeout = (int)remaining;

                        if (socketTimeout > totalTimeout)
                        {
                            socketTimeout = totalTimeout;
                        }
                    }
                }

                if (!isClientTimeout && policy.sleepBetweenRetries > 0)
                {
                    // Sleep before trying again.
                    Util.Sleep(policy.sleepBetweenRetries);
                }

                iteration++;

                if (!PrepareRetry(isClientTimeout || exception.Result != ResultCode.SERVER_NOT_AVAILABLE))
                {
                    // Batch may be retried in separate commands.
                    if (RetryBatch(cluster, socketTimeout, totalTimeout, deadline, iteration, commandSentCounter))
                    {
                        // Batch was retried in separate commands.  Complete this command.
                        return;
                    }
                }
            }

            // Retries have been exhausted.  Throw last exception.
            if (isClientTimeout)
            {
                exception = new AerospikeException.Timeout(policy, true);
            }
            exception.Node      = node;
            exception.Policy    = policy;
            exception.Iteration = iteration;
            exception.SetInDoubt(IsWrite(), commandSentCounter);
            throw exception;
        }
        public void Authenticate(Connection conn, byte[] user, byte[] password)
        {
            SetAuthenticate(user, password);
            conn.Write(dataBuffer, dataOffset);
            conn.ReadFully(dataBuffer, HEADER_SIZE);

            int result = dataBuffer[RESULT_CODE];
            if (result != 0)
            {
                throw new AerospikeException(result, "Authentication failed");
            }
        }
        public void Login(Cluster cluster, Connection conn, out byte[] sessionToken, out DateTime?sessionExpiration)
        {
            sessionToken      = null;
            sessionExpiration = null;
            dataOffset        = 8;

            conn.SetTimeout(cluster.loginTimeout);

            try
            {
                if (cluster.authMode == AuthMode.INTERNAL)
                {
                    WriteHeader(LOGIN, 2);
                    WriteField(USER, cluster.user);
                    WriteField(CREDENTIAL, cluster.passwordHash);
                }
                else
                {
                    WriteHeader(LOGIN, 3);
                    WriteField(USER, cluster.user);
                    WriteField(CREDENTIAL, cluster.passwordHash);
                    WriteField(CLEAR_PASSWORD, cluster.password);
                }
                WriteSize();
                conn.Write(dataBuffer, dataOffset);
                conn.ReadFully(dataBuffer, HEADER_SIZE);

                int result = dataBuffer[RESULT_CODE];

                if (result != 0)
                {
                    if (result == INVALID_COMMAND)
                    {
                        // New login not supported.  Try old authentication.
                        AuthenticateOld(cluster, conn);
                        return;
                    }

                    // login failed.
                    throw new AerospikeException(result, "Login failed");
                }

                // Read session token.
                long size        = ByteUtil.BytesToLong(dataBuffer, 0);
                int  receiveSize = ((int)(size & 0xFFFFFFFFFFFFL)) - HEADER_REMAINING;
                int  fieldCount  = dataBuffer[11];

                if (receiveSize <= 0 || receiveSize > dataBuffer.Length || fieldCount <= 0)
                {
                    throw new AerospikeException(result, "Failed to retrieve session token");
                }

                conn.ReadFully(dataBuffer, receiveSize);
                dataOffset = 0;

                for (int i = 0; i < fieldCount; i++)
                {
                    int len = ByteUtil.BytesToInt(dataBuffer, dataOffset);
                    dataOffset += 4;
                    int id = dataBuffer[dataOffset++];
                    len--;

                    if (id == SESSION_TOKEN)
                    {
                        sessionToken = new byte[len];
                        Array.Copy(dataBuffer, dataOffset, sessionToken, 0, len);
                    }
                    else if (id == SESSION_TTL)
                    {
                        // Subtract 60 seconds from ttl so client session expires before server session.
                        long seconds = ByteUtil.BytesToUInt(dataBuffer, dataOffset) - 60;

                        if (seconds > 0)
                        {
                            sessionExpiration = DateTime.UtcNow.AddSeconds(seconds);
                        }
                        else
                        {
                            Log.Warn("Invalid session TTL: " + seconds);
                        }
                    }
                    dataOffset += len;
                }

                if (sessionToken == null)
                {
                    throw new AerospikeException(result, "Failed to retrieve session token");
                }
            }
            finally
            {
                conn.SetTimeout(cluster.connectionTimeout);
            }
        }
예제 #11
0
        public void Execute()
        {
            Policy    policy          = GetPolicy();
            int       remainingMillis = policy.timeout;
            DateTime  limit           = DateTime.UtcNow.AddMilliseconds(remainingMillis);
            Node      node            = null;
            Exception exception       = null;
            int       failedNodes     = 0;
            int       failedConns     = 0;
            int       iterations      = 0;

            dataBuffer = ThreadLocalData.GetBuffer();

            // Execute command until successful, timed out or maximum iterations have been reached.
            while (true)
            {
                try
                {
                    node = GetNode();
                    Connection conn = node.GetConnection(remainingMillis);

                    try
                    {
                        // Set command buffer.
                        WriteBuffer();

                        // Reset timeout in send buffer (destined for server) and socket.
                        ByteUtil.IntToBytes((uint)remainingMillis, dataBuffer, 22);

                        // Send command.
                        conn.Write(dataBuffer, dataOffset);

                        // Parse results.
                        ParseResult(conn);

                        // Reflect healthy status.
                        conn.UpdateLastUsed();

                        // Put connection back in pool.
                        node.PutConnection(conn);

                        // Command has completed successfully.  Exit method.
                        return;
                    }
                    catch (AerospikeException ae)
                    {
                        if (ae.KeepConnection())
                        {
                            // Put connection back in pool.
                            conn.UpdateLastUsed();
                            node.PutConnection(conn);
                        }
                        else
                        {
                            // Close socket to flush out possible garbage.  Do not put back in pool.
                            node.CloseConnection(conn);
                        }
                        throw;
                    }
                    catch (SocketException ioe)
                    {
                        node.CloseConnection(conn);

                        if (ioe.ErrorCode == (int)SocketError.TimedOut)
                        {
                            // Full timeout has been reached.  Do not retry.
                            // Close socket to flush out possible garbage.  Do not put back in pool.
                            throw new AerospikeException.Timeout(node, policy.timeout, ++iterations, failedNodes, failedConns);
                        }
                        else
                        {
                            // IO errors are considered temporary anomalies.  Retry.
                            // Close socket to flush out possible garbage.  Do not put back in pool.
                            exception = ioe;
                        }
                    }
                    catch (Exception)
                    {
                        // All runtime exceptions are considered fatal.  Do not retry.
                        // Close socket to flush out possible garbage.  Do not put back in pool.
                        node.CloseConnection(conn);
                        throw;
                    }
                }
                catch (AerospikeException.InvalidNode ine)
                {
                    // Node is currently inactive.  Retry.
                    exception = ine;
                    failedNodes++;
                }
                catch (AerospikeException.Connection ce)
                {
                    // Socket connection error has occurred. Retry.
                    exception = ce;
                    failedConns++;
                }

                if (++iterations > policy.maxRetries)
                {
                    break;
                }

                // Check for client timeout.
                if (policy.timeout > 0)
                {
                    remainingMillis = (int)limit.Subtract(DateTime.UtcNow).TotalMilliseconds - policy.sleepBetweenRetries;

                    if (remainingMillis <= 0)
                    {
                        break;
                    }
                }

                if (policy.sleepBetweenRetries > 0)
                {
                    // Sleep before trying again.
                    Util.Sleep(policy.sleepBetweenRetries);
                }

                // Reset node reference and try again.
                node = null;
            }

            // Retries have been exhausted.  Throw last exception.
            throw exception;
        }
예제 #12
0
        public void Execute(Cluster cluster, Policy policy, Key key, Node node, bool isRead)
        {
            Partition          partition = (key != null)? new Partition(key) : null;
            AerospikeException exception = null;
            DateTime           deadline  = DateTime.MinValue;
            int  socketTimeout           = policy.socketTimeout;
            int  totalTimeout            = policy.totalTimeout;
            int  iteration          = 0;
            int  commandSentCounter = 0;
            bool isClientTimeout;

            if (totalTimeout > 0)
            {
                deadline = DateTime.UtcNow.AddMilliseconds(totalTimeout);

                if (socketTimeout == 0 || socketTimeout > totalTimeout)
                {
                    socketTimeout = totalTimeout;
                }
            }

            // Execute command until successful, timed out or maximum iterations have been reached.
            while (true)
            {
                try
                {
                    if (partition != null)
                    {
                        // Single record command node retrieval.
                        node = GetNode(cluster, partition, policy.replica, isRead);
                    }

                    Connection conn = node.GetConnection(socketTimeout);

                    try
                    {
                        // Set command buffer.
                        WriteBuffer();

                        // Check if timeout needs to be changed in send buffer.
                        if (totalTimeout != policy.totalTimeout)
                        {
                            // Reset timeout in send buffer (destined for server) and socket.
                            ByteUtil.IntToBytes((uint)totalTimeout, dataBuffer, 22);
                        }

                        // Send command.
                        conn.Write(dataBuffer, dataOffset);
                        commandSentCounter++;

                        // Parse results.
                        ParseResult(conn);

                        // Put connection back in pool.
                        node.PutConnection(conn);

                        // Command has completed successfully.  Exit method.
                        return;
                    }
                    catch (AerospikeException ae)
                    {
                        if (ae.KeepConnection())
                        {
                            // Put connection back in pool.
                            node.PutConnection(conn);
                        }
                        else
                        {
                            // Close socket to flush out possible garbage.  Do not put back in pool.
                            node.CloseConnection(conn);
                        }

                        if (ae.Result == ResultCode.TIMEOUT)
                        {
                            // Go through retry logic on server timeout.
                            exception       = new AerospikeException.Timeout(node, policy, iteration + 1, false);
                            isClientTimeout = false;

                            if (isRead)
                            {
                                base.sequence++;
                            }
                        }
                        else
                        {
                            ae.SetInDoubt(isRead, commandSentCounter);
                            throw;
                        }
                    }
                    catch (SocketException se)
                    {
                        // Socket errors are considered temporary anomalies.
                        // Retry after closing connection.
                        node.CloseConnection(conn);

                        if (se.SocketErrorCode == SocketError.TimedOut)
                        {
                            isClientTimeout = true;

                            if (isRead)
                            {
                                base.sequence++;
                            }
                        }
                        else
                        {
                            exception       = new AerospikeException(se);
                            isClientTimeout = false;
                            base.sequence++;
                        }
                    }
                    catch (Exception)
                    {
                        // All other exceptions are considered fatal.  Do not retry.
                        // Close socket to flush out possible garbage.  Do not put back in pool.
                        node.CloseConnection(conn);
                        throw;
                    }
                }
                catch (AerospikeException.Connection ce)
                {
                    // Socket connection error has occurred. Retry.
                    exception       = ce;
                    isClientTimeout = false;
                    base.sequence++;
                }

                // Check maxRetries.
                if (++iteration > policy.maxRetries)
                {
                    break;
                }

                if (policy.totalTimeout > 0)
                {
                    // Check for total timeout.
                    long remaining = (long)deadline.Subtract(DateTime.UtcNow).TotalMilliseconds - policy.sleepBetweenRetries;

                    if (remaining <= 0)
                    {
                        break;
                    }

                    if (remaining < totalTimeout)
                    {
                        totalTimeout = (int)remaining;

                        if (socketTimeout > totalTimeout)
                        {
                            socketTimeout = totalTimeout;
                        }
                    }
                }

                if (!isClientTimeout && policy.sleepBetweenRetries > 0)
                {
                    // Sleep before trying again.
                    Util.Sleep(policy.sleepBetweenRetries);
                }
            }

            // Retries have been exhausted.  Throw last exception.
            if (isClientTimeout)
            {
                exception = new AerospikeException.Timeout(node, policy, iteration, true);
            }
            exception.SetInDoubt(isRead, commandSentCounter);
            throw exception;
        }
예제 #13
0
        public void Execute
        (
            Cluster cluster, Policy policy, Partition partition, Node node, bool isRead,
            int socketTimeout, int totalTimeout, DateTime deadline, int iteration, int commandSentCounter
        )
        {
            AerospikeException exception = null;
            bool isClientTimeout;

            // Execute command until successful, timed out or maximum iterations have been reached.
            while (true)
            {
                if (partition != null)
                {
                    // Single record command node retrieval.
                    try
                    {
                        node = GetNode(cluster, policy, partition, isRead);
                    }
                    catch (AerospikeException ae)
                    {
                        ae.Iteration = iteration;
                        ae.SetInDoubt(isRead, commandSentCounter);
                        throw;
                    }
                }

                try
                {
                    Connection conn = node.GetConnection(socketTimeout);

                    try
                    {
                        // Set command buffer.
                        WriteBuffer();

                        // Check if timeout needs to be changed in send buffer.
                        if (totalTimeout != policy.totalTimeout)
                        {
                            // Reset timeout in send buffer (destined for server) and socket.
                            ByteUtil.IntToBytes((uint)totalTimeout, dataBuffer, 22);
                        }

                        // Send command.
                        conn.Write(dataBuffer, dataOffset);
                        commandSentCounter++;

                        // Parse results.
                        ParseResult(conn);

                        // Put connection back in pool.
                        node.PutConnection(conn);

                        // Command has completed successfully.  Exit method.
                        return;
                    }
                    catch (AerospikeException ae)
                    {
                        if (ae.KeepConnection())
                        {
                            // Put connection back in pool.
                            node.PutConnection(conn);
                        }
                        else
                        {
                            // Close socket to flush out possible garbage.  Do not put back in pool.
                            node.CloseConnection(conn);
                        }

                        if (ae.Result == ResultCode.TIMEOUT)
                        {
                            // Go through retry logic on server timeout.
                            exception       = new AerospikeException.Timeout(policy, false);
                            isClientTimeout = false;
                            ShiftSequenceOnRead(policy, isRead);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    catch (SocketException se)
                    {
                        // Socket errors are considered temporary anomalies.
                        // Retry after closing connection.
                        node.CloseConnection(conn);

                        if (se.SocketErrorCode == SocketError.TimedOut)
                        {
                            isClientTimeout = true;
                            ShiftSequenceOnRead(policy, isRead);
                        }
                        else
                        {
                            exception       = new AerospikeException(se);
                            isClientTimeout = false;
                            base.sequence++;
                        }
                    }
                    catch (Exception)
                    {
                        // All other exceptions are considered fatal.  Do not retry.
                        // Close socket to flush out possible garbage.  Do not put back in pool.
                        node.CloseConnection(conn);
                        throw;
                    }
                }
                catch (SocketException se)
                {
                    // This exception might happen after initial connection succeeded, but
                    // user login failed with a socket error.  Retry.
                    if (se.SocketErrorCode == SocketError.TimedOut)
                    {
                        isClientTimeout = true;
                        ShiftSequenceOnRead(policy, isRead);
                    }
                    else
                    {
                        exception       = new AerospikeException(se);
                        isClientTimeout = false;
                        base.sequence++;
                    }
                }
                catch (AerospikeException.Connection ce)
                {
                    // Socket connection error has occurred. Retry.
                    exception       = ce;
                    isClientTimeout = false;
                    base.sequence++;
                }
                catch (AerospikeException ae)
                {
                    ae.Node      = node;
                    ae.Iteration = iteration;
                    ae.SetInDoubt(isRead, commandSentCounter);
                    throw;
                }

                // Check maxRetries.
                if (iteration > policy.maxRetries)
                {
                    break;
                }

                if (policy.totalTimeout > 0)
                {
                    // Check for total timeout.
                    long remaining = (long)deadline.Subtract(DateTime.UtcNow).TotalMilliseconds - policy.sleepBetweenRetries;

                    if (remaining <= 0)
                    {
                        break;
                    }

                    if (remaining < totalTimeout)
                    {
                        totalTimeout = (int)remaining;

                        if (socketTimeout > totalTimeout)
                        {
                            socketTimeout = totalTimeout;
                        }
                    }
                }

                if (!isClientTimeout && policy.sleepBetweenRetries > 0)
                {
                    // Sleep before trying again.
                    Util.Sleep(policy.sleepBetweenRetries);
                }

                iteration++;

                if (ShouldRetryBatch() && RetryBatch(cluster, socketTimeout, totalTimeout, deadline, iteration, commandSentCounter))
                {
                    // Batch retried in separate commands.  Complete this command.
                    return;
                }
            }

            // Retries have been exhausted.  Throw last exception.
            if (isClientTimeout)
            {
                exception = new AerospikeException.Timeout(policy, true);
            }
            exception.Node      = node;
            exception.Iteration = iteration;
            exception.SetInDoubt(isRead, commandSentCounter);
            throw exception;
        }