You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Yashasvi Kotamraju (JIRA)" <ji...@apache.org> on 2018/04/05 07:26:00 UTC

[jira] [Commented] (IGNITE-6252) Cassandra Cache Store Session does not retry if prepare statement failed

    [ https://issues.apache.org/jira/browse/IGNITE-6252?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16426566#comment-16426566 ] 

Yashasvi Kotamraju commented on IGNITE-6252:
--------------------------------------------

*In CassandraSessionImpl.java*  

*In method* 

*@Override public <R, V> R execute(BatchExecutionAssistant<R, V> assistant, Iterable<? extends V> data)*

*.................*

*ResultSet resSet = futureResult.getValue().getUninterruptibly();*
 *Row row = resSet != null && resSet.iterator().hasNext() ? resSet.iterator().next() : null;*

*if (row != null)*
 *assistant.process(row, futureResult.getKey());*

*...................*

If prepared statements are Insert/Update/Delete then no result will be returned according to Cassandra docs. Hence{color:#FF0000} {color}*resSet.iterator().hasNext()* will always return false and so *row* will always be null. Hence its not added to *assistant.process* so *assistant.processedCount()* will always be 0. and never be equal to *datasize*. We end up retrying eventhough it was inserted/deleted/updated and there were no Exceptions, and try CQL_EXECUTION_ATTEMPTS_COUNT attempts trying again and again and finally throw Exception :

*"Failed to process " + (dataSize - assistant.processedCount()) +*
 *" of " + dataSize + " elements, during " + assistant.operationName() +*
 *" operation with Cassandra"*  

Hence the code fix using the condition : assistant.processedCount() == dataSize will not work if prepared statement is not a select statement.

We can put a boolean flag *retry* which is set to false initially in every attempt. If at any point the execution flow enters Exception code block then we can set *retry* as true. Then instead of condition :

*if (tblAbsenceEx == null && hostsAvailEx == null && prepStatEx == null)*

we can use:

 *if(!retry)*

as a condition on whether to return the processed data or retry.

In addition to this we need to maintain separate HashSet of  keyvalues of ResultSetFuture where 

*resSet !=null  && (* *resSet.iterator().hasNext()* == *false)*  Which is the case for Insert/Upadate/Delete preparedstatements.

Then while re attempting in addition to !assistant.alreadyProcessed(seqNum) check we also check if the HashSet does not contains the seqNum.  

 

> Cassandra Cache Store Session does not retry if prepare statement failed
> ------------------------------------------------------------------------
>
>                 Key: IGNITE-6252
>                 URL: https://issues.apache.org/jira/browse/IGNITE-6252
>             Project: Ignite
>          Issue Type: Bug
>          Components: cassandra
>    Affects Versions: 2.0, 2.1
>            Reporter: Sunny Chan
>            Assignee: Igor Rudyak
>            Priority: Major
>             Fix For: 2.5
>
>
> During our testing, we have found that certain warning about prepared statement:
> 2017-08-31 11:27:19.479 org.apache.ignite.cache.store.cassandra.CassandraCacheStore flusher-0-#265%xxxx% WARN CassandraCacheStore - Prepared statement cluster error detected, refreshing Cassandra session
> com.datastax.driver.core.exceptions.InvalidQueryException: Tried to execute unknown prepared query : 0xc7647611fd755386ef63478ee7de577b. You may have used a PreparedStatement that was created with another Cluster instance.
> We notice that after this warning occurs some of the data didn't persist properly in cassandra cache. After further examining the Ignite's CassandraSessionImpl code in method execute(BatchExecutionAssistance,Iterable), we found that at around [line 283|https://github.com/apache/ignite/blob/86bd544a557663bce497134f7826be6b24d53330/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java#L283], if the prepare statement fails in the asnyc call, it will not retry the operation as the error is stored in [line 269|https://github.com/apache/ignite/blob/86bd544a557663bce497134f7826be6b24d53330/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java#L269] and cleared in [line 277|https://github.com/apache/ignite/blob/86bd544a557663bce497134f7826be6b24d53330/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java#L277] but it was not checked again after going through the [ResultSetFuture |https://github.com/apache/ignite/blob/86bd544a557663bce497134f7826be6b24d53330/modules/cassandra/store/src/main/java/org/apache/ignite/cache/store/cassandra/session/CassandraSessionImpl.java#L307].
> I believe in line 307 you should check for error != null such that any failure will be retry.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)