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

Brandon Williams commented on CASSANDRA-3339:
---------------------------------------------

FWIW, I think this is likely a thrift problem, akin to THRIFT-968.  Anytime you 
do anything invalid with a thrift connection you have to throw it away, even if 
it did not send or receive anything.
                
> Invalid queries in Cassandra.Client causes subsequent, valid, queries to fail
> -----------------------------------------------------------------------------
>
>                 Key: CASSANDRA-3339
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-3339
>             Project: Cassandra
>          Issue Type: Bug
>          Components: API
>    Affects Versions: 0.8.6
>         Environment: Windows
>            Reporter: Ivo Ladage-van Doorn
>
> First of all; I'm quite new to Cassandra, so I hope that my analysis is 
> correct. 
> I am using the Hector client to perform queries on Cassandra. The problem is 
> that once I invoked an invalid slice query with a null rowKey, subsequent 
> queries also fail with roughly the same error. So the first time I invoke the 
> invalid query, I get this exception:
> org.apache.thrift.protocol.TProtocolException: Required field 'key' was not 
> present! 
> Struct: get_slice_args(key:null, 
> column_parent:ColumnParent(column_family:AmdatuToken), 
> predicate:SlicePredicate(slice_range:SliceRange(start:, finish:, 
> reversed:false, count:1000000)), consistency_level:ONE)
>        at 
> me.prettyprint.cassandra.service.ExceptionsTranslatorImpl.translate(ExceptionsTranslatorImpl.java:56)
>        at 
> me.prettyprint.cassandra.service.KeyspaceServiceImpl$7.execute(KeyspaceServiceImpl.java:285)
>        at 
> me.prettyprint.cassandra.service.KeyspaceServiceImpl$7.execute(KeyspaceServiceImpl.java:268)
>        ...
> which is expected behavior. However, after invoking this invalid query, 
> subsequent valid calls also fail with roughly the same error:
> me.prettyprint.hector.api.exceptions.HCassandraInternalException: Cassandra 
> encountered an internal error processing this request: TApplicationError 
> type: 7 message:Required field 'key' was not present! Struct: 
> get_slice_args(key:null, column_parent:null, predicate:null, 
> consistency_level:ONE) 
> org.apache.felix.log.LogException: 
> me.prettyprint.hector.api.exceptions.HCassandraInternalException: 
> Cassandra encountered an internal error processing this request: 
> TApplicationError type: 7 message:Required field 'key' was not present! 
> Struct: get_slice_args(key:null, column_parent:null, predicate:null, 
> consistency_level:ONE)
>         at 
> me.prettyprint.cassandra.service.ExceptionsTranslatorImpl.translate(ExceptionsTranslatorImpl.java:29)
>         at 
> me.prettyprint.cassandra.service.KeyspaceServiceImpl$2.execute(KeyspaceServiceImpl.java:121)
>         at 
> me.prettyprint.cassandra.service.KeyspaceServiceImpl$2.execute(KeyspaceServiceImpl.java:114)
>         ...
> In the case of Hector it goes downhill from there, ending in socket write 
> errors and marking the Cassandra host as being down.
> Now this is what I think happens:
> The Hector client uses the org.apache.cassandra.thrift.Cassandra.Client class 
> to execute the queries on Cassandra.
> When I perform a Thrift slice query from Hector, it invokes the get_slice 
> method in the Cassandra.Client, which in its turn invokes send_get_slice. In 
> my case a bug in my own software caused an invocation of this method with a 
> rowKey that equals null. Now although the rowKey is invalid, the method call 
> continues all the way to send_get_slice. This send_get_slice method looks 
> like this:
> (from org.apache.cassandra.thrift.Cassandra)
> public void send_get_slice(ByteBuffer key, ColumnParent column_parent, 
> SlicePredicate predicate, ConsistencyLevel consistency_level) throws 
> org.apache.thrift.TException
> {
>   oprot_.writeMessageBegin(new 
> org.apache.thrift.protocol.TMessage("get_slice", 
> org.apache.thrift.protocol.TMessageType.CALL, ++seqid_));
>   get_slice_args args = new get_slice_args();
>   args.setKey(key);
>   args.setColumn_parent(column_parent);
>   args.setPredicate(predicate);
>   args.setConsistency_level(consistency_level);
>   args.write(oprot_);
>   oprot_.writeMessageEnd();
>   oprot_.getTransport().flush();
> }
> The problem is that the TMessage is written to the output protocol at the 
> first line. When subsequently the arguments are written in 
> args.write(oprot_), it first calls validate(). The validate() method detects 
> the null rowKey and throws an exception:
> public void validate() throws org.apache.thrift.TException {
>   // check for required fields
>   if (key == null) {
>     throw new org.apache.thrift.protocol.TProtocolException("Required field 
> 'key' was not present! Struct: " + toString());
>   }
>   ...
> }
>     
> Now Hector finally catches the exception and returns the Cassandra client to 
> its connection pool. When that Cassandra client is drawn from the pool and 
> reused for another query, it still has the TMessage written to its oprot, 
> resulting in another failed call. Call reusing this client from the 
> connection pool keep getting such errors, and in the end result in socket 
> write errors.
> The problem is not only restricted to this particular method by the way, the 
> same construct is used in many more methods in this class. Also passing a 
> null value for columnsPath or ConsistencyLevel seems to cause the same issue.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to