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:


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

Reply via email to