Search in sources :

Example 1 with ConnectionRecover

use of com.aerospike.client.cluster.ConnectionRecover in project aerospike-client-java by aerospike.

the class SyncCommand method executeCommand.

public final void executeCommand() {
    // final long tranId = TranCounter.getAndIncrement();
    Node node;
    AerospikeException exception = null;
    boolean isClientTimeout;
    // Execute command until successful, timed out or maximum iterations have been reached.
    while (true) {
        try {
            node = getNode();
        } catch (AerospikeException ae) {
            if (cluster.isActive()) {
                // Log.info("Throw AerospikeException: " + tranId + ',' + node + ',' + sequence + ',' + iteration + ',' + ae.getResultCode());
                ae.setPolicy(policy);
                ae.setIteration(iteration);
                ae.setInDoubt(isWrite(), commandSentCounter);
                throw ae;
            } else {
                throw new AerospikeException("Cluster has been closed");
            }
        }
        try {
            node.validateErrorCount();
            Connection conn = node.getConnection(policy.connectTimeout, socketTimeout, policy.timeoutDelay);
            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.getResultCode() == ResultCode.TIMEOUT) {
                    // Retry on server timeout.
                    // Log.info("Server timeout: " + tranId + ',' + node + ',' + sequence + ',' + iteration);
                    exception = new AerospikeException.Timeout(policy, false);
                    isClientTimeout = false;
                    node.incrErrorCount();
                } else if (ae.getResultCode() == ResultCode.DEVICE_OVERLOAD) {
                    // Add to circuit breaker error count and retry.
                    exception = ae;
                    isClientTimeout = false;
                    node.incrErrorCount();
                } else {
                    throw ae;
                }
            } catch (Connection.ReadTimeout crt) {
                if (policy.timeoutDelay > 0) {
                    cluster.recoverConnection(new ConnectionRecover(conn, node, policy.timeoutDelay, crt, isSingle()));
                } else {
                    node.closeConnection(conn);
                }
                isClientTimeout = true;
            } catch (RuntimeException re) {
                // All runtime exceptions are considered fatal.  Do not retry.
                // Close socket to flush out possible garbage.  Do not put back in pool.
                // Log.info("Throw RuntimeException: " + tranId + ',' + node + ',' + sequence + ',' + iteration);
                node.closeConnection(conn);
                throw re;
            } catch (SocketTimeoutException ste) {
                // Full timeout has been reached.
                // Log.info("Socket timeout: " + tranId + ',' + node + ',' + sequence + ',' + iteration);
                node.closeConnection(conn);
                isClientTimeout = true;
            } catch (IOException ioe) {
                // IO errors are considered temporary anomalies.  Retry.
                // Log.info("IOException: " + tranId + ',' + node + ',' + sequence + ',' + iteration);
                node.closeConnection(conn);
                exception = new AerospikeException.Connection(ioe);
                isClientTimeout = false;
            }
        } catch (Connection.ReadTimeout crt) {
            // Connection already handled.
            isClientTimeout = true;
        } catch (AerospikeException.Connection ce) {
            // Socket connection error has occurred. Retry.
            // Log.info("Connection error: " + tranId + ',' + node + ',' + sequence + ',' + iteration);
            exception = ce;
            isClientTimeout = false;
        } catch (AerospikeException.Backoff be) {
            // Node is in backoff state. Retry, hopefully on another node.
            // Log.info("Backoff error: " + tranId + ',' + node + ',' + sequence + ',' + iteration);
            exception = be;
            isClientTimeout = false;
        } catch (AerospikeException ae) {
            // Log.info("Throw AerospikeException: " + tranId + ',' + node + ',' + sequence + ',' + iteration + ',' + ae.getResultCode());
            ae.setNode(node);
            ae.setPolicy(policy);
            ae.setIteration(iteration);
            ae.setInDoubt(isWrite(), commandSentCounter);
            throw ae;
        }
        // Check maxRetries.
        if (iteration > maxRetries) {
            break;
        }
        if (totalTimeout > 0) {
            // Check for total timeout.
            long remaining = deadline - System.nanoTime() - TimeUnit.MILLISECONDS.toNanos(policy.sleepBetweenRetries);
            if (remaining <= 0) {
                break;
            }
            // Convert back to milliseconds for remaining check.
            remaining = TimeUnit.NANOSECONDS.toMillis(remaining);
            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.getResultCode() != 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) {
        // Log.info("SocketTimeoutException: " + tranId + ',' + sequence + ',' + iteration);
        exception = new AerospikeException.Timeout(policy, true);
    }
    // Log.info("Runtime exception: " + tranId + ',' + sequence + ',' + iteration + ',' + exception.getMessage());
    exception.setNode(node);
    exception.setPolicy(policy);
    exception.setIteration(iteration);
    exception.setInDoubt(isWrite(), commandSentCounter);
    throw exception;
}
Also used : AerospikeException(com.aerospike.client.AerospikeException) Node(com.aerospike.client.cluster.Node) Connection(com.aerospike.client.cluster.Connection) IOException(java.io.IOException) SocketTimeoutException(java.net.SocketTimeoutException) ConnectionRecover(com.aerospike.client.cluster.ConnectionRecover)

Aggregations

AerospikeException (com.aerospike.client.AerospikeException)1 Connection (com.aerospike.client.cluster.Connection)1 ConnectionRecover (com.aerospike.client.cluster.ConnectionRecover)1 Node (com.aerospike.client.cluster.Node)1 IOException (java.io.IOException)1 SocketTimeoutException (java.net.SocketTimeoutException)1