Search in sources :

Example 1 with RandomSleeper

use of org.apache.ignite.cache.store.cassandra.common.RandomSleeper in project ignite by apache.

the class CassandraSessionImpl method execute.

/** {@inheritDoc} */
@Override
public void execute(BatchLoaderAssistant assistant) {
    int attempt = 0;
    String errorMsg = "Failed to execute Cassandra " + assistant.operationName() + " operation";
    Throwable error = new IgniteException(errorMsg);
    RandomSleeper sleeper = newSleeper();
    incrementSessionRefs();
    try {
        while (attempt < CQL_EXECUTION_ATTEMPTS_COUNT) {
            if (attempt != 0)
                log.warning("Trying " + (attempt + 1) + " attempt to load Ignite cache");
            Statement statement = tuneStatementExecutionOptions(assistant.getStatement());
            try {
                ResultSetFuture fut = session().executeAsync(statement);
                ResultSet resSet = fut.getUninterruptibly();
                if (resSet == null || !resSet.iterator().hasNext())
                    return;
                for (Row row : resSet) assistant.process(row);
                return;
            } catch (Throwable e) {
                error = e;
                if (CassandraHelper.isTableAbsenceError(e))
                    return;
                else if (CassandraHelper.isHostsAvailabilityError(e))
                    handleHostsAvailabilityError(e, attempt, errorMsg);
                else if (CassandraHelper.isPreparedStatementClusterError(e))
                    handlePreparedStatementClusterError(e);
                else
                    // For an error which we don't know how to handle, we will not try next attempts and terminate.
                    throw new IgniteException(errorMsg, e);
            }
            sleeper.sleep();
            attempt++;
        }
    } catch (Throwable e) {
        error = e;
    } finally {
        decrementSessionRefs();
    }
    log.error(errorMsg, error);
    throw new IgniteException(errorMsg, error);
}
Also used : ResultSetFuture(com.datastax.driver.core.ResultSetFuture) IgniteException(org.apache.ignite.IgniteException) PreparedStatement(com.datastax.driver.core.PreparedStatement) BoundStatement(com.datastax.driver.core.BoundStatement) BatchStatement(com.datastax.driver.core.BatchStatement) Statement(com.datastax.driver.core.Statement) ResultSet(com.datastax.driver.core.ResultSet) RandomSleeper(org.apache.ignite.cache.store.cassandra.common.RandomSleeper) Row(com.datastax.driver.core.Row)

Example 2 with RandomSleeper

use of org.apache.ignite.cache.store.cassandra.common.RandomSleeper in project ignite by apache.

the class CassandraSessionImpl method execute.

/** {@inheritDoc} */
@Override
public void execute(List<Mutation> mutations) {
    if (mutations == null || mutations.isEmpty())
        return;
    Throwable error = null;
    String errorMsg = "Failed to apply " + mutations.size() + " mutations performed withing Ignite " + "transaction into Cassandra";
    int attempt = 0;
    boolean tableExistenceRequired = false;
    Map<String, PreparedStatement> statements = new HashMap<>();
    Map<String, KeyValuePersistenceSettings> tableSettings = new HashMap<>();
    RandomSleeper sleeper = newSleeper();
    incrementSessionRefs();
    try {
        while (attempt < CQL_EXECUTION_ATTEMPTS_COUNT) {
            error = null;
            if (attempt != 0) {
                log.warning("Trying " + (attempt + 1) + " attempt to apply " + mutations.size() + " mutations " + "performed withing Ignite transaction into Cassandra");
            }
            try {
                BatchStatement batch = new BatchStatement();
                // accumulating all the mutations into one Cassandra logged batch
                for (Mutation mutation : mutations) {
                    String key = mutation.getTable() + mutation.getClass().getName();
                    PreparedStatement st = statements.get(key);
                    if (st == null) {
                        st = prepareStatement(mutation.getTable(), mutation.getStatement(), mutation.getPersistenceSettings(), mutation.tableExistenceRequired());
                        if (st != null)
                            statements.put(key, st);
                    }
                    if (st != null)
                        batch.add(mutation.bindStatement(st));
                    if (attempt == 0) {
                        if (mutation.tableExistenceRequired()) {
                            tableExistenceRequired = true;
                            if (!tableSettings.containsKey(mutation.getTable()))
                                tableSettings.put(mutation.getTable(), mutation.getPersistenceSettings());
                        }
                    }
                }
                // committing logged batch into Cassandra
                if (batch.size() > 0)
                    session().execute(tuneStatementExecutionOptions(batch));
                return;
            } catch (Throwable e) {
                error = e;
                if (CassandraHelper.isTableAbsenceError(e)) {
                    if (tableExistenceRequired) {
                        for (Map.Entry<String, KeyValuePersistenceSettings> entry : tableSettings.entrySet()) handleTableAbsenceError(entry.getKey(), entry.getValue());
                    } else
                        return;
                } else if (CassandraHelper.isHostsAvailabilityError(e)) {
                    if (handleHostsAvailabilityError(e, attempt, errorMsg))
                        statements.clear();
                } else if (CassandraHelper.isPreparedStatementClusterError(e)) {
                    handlePreparedStatementClusterError(e);
                    statements.clear();
                } else {
                    // For an error which we don't know how to handle, we will not try next attempts and terminate.
                    throw new IgniteException(errorMsg, e);
                }
            }
            if (!CassandraHelper.isTableAbsenceError(error))
                sleeper.sleep();
            attempt++;
        }
    } catch (Throwable e) {
        error = e;
    } finally {
        decrementSessionRefs();
    }
    log.error(errorMsg, error);
    throw new IgniteException(errorMsg, error);
}
Also used : HashMap(java.util.HashMap) PreparedStatement(com.datastax.driver.core.PreparedStatement) KeyValuePersistenceSettings(org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings) IgniteException(org.apache.ignite.IgniteException) BatchStatement(com.datastax.driver.core.BatchStatement) RandomSleeper(org.apache.ignite.cache.store.cassandra.common.RandomSleeper) Mutation(org.apache.ignite.cache.store.cassandra.session.transaction.Mutation)

Example 3 with RandomSleeper

use of org.apache.ignite.cache.store.cassandra.common.RandomSleeper in project ignite by apache.

the class CassandraSessionImpl method execute.

/** {@inheritDoc} */
@Override
public <R, V> R execute(BatchExecutionAssistant<R, V> assistant, Iterable<? extends V> data) {
    if (data == null || !data.iterator().hasNext())
        return assistant.processedData();
    int attempt = 0;
    String errorMsg = "Failed to execute Cassandra " + assistant.operationName() + " operation";
    Throwable error = new IgniteException(errorMsg);
    RandomSleeper sleeper = newSleeper();
    int dataSize = 0;
    incrementSessionRefs();
    try {
        while (attempt < CQL_EXECUTION_ATTEMPTS_COUNT) {
            if (attempt != 0) {
                log.warning("Trying " + (attempt + 1) + " attempt to execute Cassandra batch " + assistant.operationName() + " operation to process rest " + (dataSize - assistant.processedCount()) + " of " + dataSize + " elements");
            }
            //clean errors info before next communication with Cassandra
            Throwable unknownEx = null;
            Throwable tblAbsenceEx = null;
            Throwable hostsAvailEx = null;
            Throwable prepStatEx = null;
            List<Cache.Entry<Integer, ResultSetFuture>> futResults = new LinkedList<>();
            PreparedStatement preparedSt = prepareStatement(assistant.getTable(), assistant.getStatement(), assistant.getPersistenceSettings(), assistant.tableExistenceRequired());
            if (preparedSt == null)
                return null;
            int seqNum = 0;
            for (V obj : data) {
                if (!assistant.alreadyProcessed(seqNum)) {
                    try {
                        Statement statement = tuneStatementExecutionOptions(assistant.bindStatement(preparedSt, obj));
                        ResultSetFuture fut = session().executeAsync(statement);
                        futResults.add(new CacheEntryImpl<>(seqNum, fut));
                    } catch (Throwable e) {
                        if (CassandraHelper.isTableAbsenceError(e)) {
                            // If there are table absence error and it is not required for the operation we can return.
                            if (!assistant.tableExistenceRequired())
                                return assistant.processedData();
                            tblAbsenceEx = e;
                            handleTableAbsenceError(assistant.getTable(), assistant.getPersistenceSettings());
                        } else if (CassandraHelper.isHostsAvailabilityError(e)) {
                            hostsAvailEx = e;
                            // Handle host availability only once.
                            if (hostsAvailEx == null)
                                handleHostsAvailabilityError(e, attempt, errorMsg);
                        } else if (CassandraHelper.isPreparedStatementClusterError(e)) {
                            prepStatEx = e;
                            handlePreparedStatementClusterError(e);
                        } else
                            unknownEx = e;
                    }
                }
                seqNum++;
            }
            dataSize = seqNum;
            // For an error which we don't know how to handle, we will not try next attempts and terminate.
            if (unknownEx != null)
                throw new IgniteException(errorMsg, unknownEx);
            // Remembering any of last errors.
            if (tblAbsenceEx != null)
                error = tblAbsenceEx;
            else if (hostsAvailEx != null)
                error = hostsAvailEx;
            else if (prepStatEx != null)
                error = prepStatEx;
            // Clean errors info before next communication with Cassandra.
            unknownEx = null;
            tblAbsenceEx = null;
            hostsAvailEx = null;
            prepStatEx = null;
            for (Cache.Entry<Integer, ResultSetFuture> futureResult : futResults) {
                try {
                    ResultSet resSet = futureResult.getValue().getUninterruptibly();
                    Row row = resSet != null && resSet.iterator().hasNext() ? resSet.iterator().next() : null;
                    if (row != null)
                        assistant.process(row, futureResult.getKey());
                } catch (Throwable e) {
                    if (CassandraHelper.isTableAbsenceError(e))
                        tblAbsenceEx = e;
                    else if (CassandraHelper.isHostsAvailabilityError(e))
                        hostsAvailEx = e;
                    else if (CassandraHelper.isPreparedStatementClusterError(e))
                        prepStatEx = e;
                    else
                        unknownEx = e;
                }
            }
            // For an error which we don't know how to handle, we will not try next attempts and terminate.
            if (unknownEx != null)
                throw new IgniteException(errorMsg, unknownEx);
            // If there are no errors occurred it means that operation successfully completed and we can return.
            if (tblAbsenceEx == null && hostsAvailEx == null && prepStatEx == null)
                return assistant.processedData();
            if (tblAbsenceEx != null) {
                // If there are table absence error and it is not required for the operation we can return.
                if (!assistant.tableExistenceRequired())
                    return assistant.processedData();
                error = tblAbsenceEx;
                handleTableAbsenceError(assistant.getTable(), assistant.getPersistenceSettings());
            }
            if (hostsAvailEx != null) {
                error = hostsAvailEx;
                handleHostsAvailabilityError(hostsAvailEx, attempt, errorMsg);
            }
            if (prepStatEx != null) {
                error = prepStatEx;
                handlePreparedStatementClusterError(prepStatEx);
            }
            if (!CassandraHelper.isTableAbsenceError(error))
                sleeper.sleep();
            attempt++;
        }
    } catch (Throwable e) {
        error = e;
    } finally {
        decrementSessionRefs();
    }
    errorMsg = "Failed to process " + (dataSize - assistant.processedCount()) + " of " + dataSize + " elements, during " + assistant.operationName() + " operation with Cassandra";
    log.error(errorMsg, error);
    throw new IgniteException(errorMsg, error);
}
Also used : ResultSetFuture(com.datastax.driver.core.ResultSetFuture) PreparedStatement(com.datastax.driver.core.PreparedStatement) BoundStatement(com.datastax.driver.core.BoundStatement) BatchStatement(com.datastax.driver.core.BatchStatement) Statement(com.datastax.driver.core.Statement) PreparedStatement(com.datastax.driver.core.PreparedStatement) LinkedList(java.util.LinkedList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IgniteException(org.apache.ignite.IgniteException) ResultSet(com.datastax.driver.core.ResultSet) RandomSleeper(org.apache.ignite.cache.store.cassandra.common.RandomSleeper) Row(com.datastax.driver.core.Row) Cache(javax.cache.Cache)

Example 4 with RandomSleeper

use of org.apache.ignite.cache.store.cassandra.common.RandomSleeper in project ignite by apache.

the class CassandraSessionImpl method execute.

/** {@inheritDoc} */
@Override
public <V> V execute(ExecutionAssistant<V> assistant) {
    int attempt = 0;
    Throwable error = null;
    String errorMsg = "Failed to execute Cassandra CQL statement: " + assistant.getStatement();
    RandomSleeper sleeper = newSleeper();
    incrementSessionRefs();
    try {
        while (attempt < CQL_EXECUTION_ATTEMPTS_COUNT) {
            error = null;
            if (attempt != 0) {
                log.warning("Trying " + (attempt + 1) + " attempt to execute Cassandra CQL statement: " + assistant.getStatement());
            }
            try {
                PreparedStatement preparedSt = prepareStatement(assistant.getTable(), assistant.getStatement(), assistant.getPersistenceSettings(), assistant.tableExistenceRequired());
                if (preparedSt == null)
                    return null;
                Statement statement = tuneStatementExecutionOptions(assistant.bindStatement(preparedSt));
                ResultSet res = session().execute(statement);
                Row row = res == null || !res.iterator().hasNext() ? null : res.iterator().next();
                return row == null ? null : assistant.process(row);
            } catch (Throwable e) {
                error = e;
                if (CassandraHelper.isTableAbsenceError(e)) {
                    if (!assistant.tableExistenceRequired()) {
                        log.warning(errorMsg, e);
                        return null;
                    }
                    handleTableAbsenceError(assistant.getTable(), assistant.getPersistenceSettings());
                } else if (CassandraHelper.isHostsAvailabilityError(e))
                    handleHostsAvailabilityError(e, attempt, errorMsg);
                else if (CassandraHelper.isPreparedStatementClusterError(e))
                    handlePreparedStatementClusterError(e);
                else
                    // For an error which we don't know how to handle, we will not try next attempts and terminate.
                    throw new IgniteException(errorMsg, e);
            }
            if (!CassandraHelper.isTableAbsenceError(error))
                sleeper.sleep();
            attempt++;
        }
    } catch (Throwable e) {
        error = e;
    } finally {
        decrementSessionRefs();
    }
    log.error(errorMsg, error);
    throw new IgniteException(errorMsg, error);
}
Also used : PreparedStatement(com.datastax.driver.core.PreparedStatement) BoundStatement(com.datastax.driver.core.BoundStatement) BatchStatement(com.datastax.driver.core.BatchStatement) Statement(com.datastax.driver.core.Statement) IgniteException(org.apache.ignite.IgniteException) ResultSet(com.datastax.driver.core.ResultSet) RandomSleeper(org.apache.ignite.cache.store.cassandra.common.RandomSleeper) PreparedStatement(com.datastax.driver.core.PreparedStatement) Row(com.datastax.driver.core.Row)

Example 5 with RandomSleeper

use of org.apache.ignite.cache.store.cassandra.common.RandomSleeper in project ignite by apache.

the class CassandraSessionImpl method prepareStatement.

/**
     * Prepares CQL statement using current Cassandra driver session.
     *
     * @param statement CQL statement.
     * @param settings Persistence settings.
     * @param tblExistenceRequired Flag indicating if table existence is required for the statement.
     * @return Prepared statement.
     */
private PreparedStatement prepareStatement(String table, String statement, KeyValuePersistenceSettings settings, boolean tblExistenceRequired) {
    int attempt = 0;
    Throwable error = null;
    String errorMsg = "Failed to prepare Cassandra CQL statement: " + statement;
    RandomSleeper sleeper = newSleeper();
    incrementSessionRefs();
    try {
        synchronized (sesStatements) {
            if (sesStatements.containsKey(statement))
                return sesStatements.get(statement);
        }
        while (attempt < CQL_EXECUTION_ATTEMPTS_COUNT) {
            try {
                PreparedStatement prepStatement = session().prepare(statement);
                synchronized (sesStatements) {
                    sesStatements.put(statement, prepStatement);
                }
                return prepStatement;
            } catch (Throwable e) {
                if (CassandraHelper.isTableAbsenceError(e)) {
                    if (!tblExistenceRequired)
                        return null;
                    handleTableAbsenceError(table, settings);
                } else if (CassandraHelper.isHostsAvailabilityError(e))
                    handleHostsAvailabilityError(e, attempt, errorMsg);
                else
                    throw new IgniteException(errorMsg, e);
                error = e;
            }
            if (!CassandraHelper.isTableAbsenceError(error))
                sleeper.sleep();
            attempt++;
        }
    } finally {
        decrementSessionRefs();
    }
    throw new IgniteException(errorMsg, error);
}
Also used : IgniteException(org.apache.ignite.IgniteException) RandomSleeper(org.apache.ignite.cache.store.cassandra.common.RandomSleeper) PreparedStatement(com.datastax.driver.core.PreparedStatement)

Aggregations

PreparedStatement (com.datastax.driver.core.PreparedStatement)5 IgniteException (org.apache.ignite.IgniteException)5 RandomSleeper (org.apache.ignite.cache.store.cassandra.common.RandomSleeper)5 BatchStatement (com.datastax.driver.core.BatchStatement)4 BoundStatement (com.datastax.driver.core.BoundStatement)3 ResultSet (com.datastax.driver.core.ResultSet)3 Row (com.datastax.driver.core.Row)3 Statement (com.datastax.driver.core.Statement)3 ResultSetFuture (com.datastax.driver.core.ResultSetFuture)2 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Cache (javax.cache.Cache)1 KeyValuePersistenceSettings (org.apache.ignite.cache.store.cassandra.persistence.KeyValuePersistenceSettings)1 Mutation (org.apache.ignite.cache.store.cassandra.session.transaction.Mutation)1