NPE using fetchMoreResults

Description

While chasing another problem using fetchMoreResults, I uncovered a NullPointerException:
Caused by: java.lang.NullPointerException
at com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Uninterruptibles.java:135)
at com.datastax.driver.core.ArrayBackedResultSet.fetchMoreResultsBlocking(ArrayBackedResultSet.java:195)
at com.datastax.driver.core.ArrayBackedResultSet.one(ArrayBackedResultSet.java:148)

This appeared on a single partition (no IN constraint on the composite primary key), reading rows from the partition in reverse order, from right to left.

It appears that with enough testing I was able to hit exactly the window where the outstanding prefetched results finished just as the primary thread was reading to the end of the current set of results. fetchMoreResultsBlocking() invokes fetchMoreResults(), where one sees the following lines:

if (fetchState.inProgress != null)
return fetchState.inProgress;

My hypothesis is that this thread sees that fetchState.inProgress is non-null, the asynchronous thread stores the new completion response, in which nextStart is non-null and inProgress is null, and this thread then returned null as the future.

The fix is to establish a single local reference to fetchState for the duration of the method, guaranteeing a consistent state, or by changing this decision to fetch the inProgress future only once:

ListenableFuture<Void> inProgress = fetchState.inProgress;
if (null != inProgress)
return inProgress;

Environment

DataStax Cassandra 2.0.7
Single node cluster
Windows dual core laptop

Pull Requests

None

Assignee

Sylvain Lebresne

Reporter

William Mitchell

Labels

None

PM Priority

None

Reproduced in

None

Affects versions

Fix versions

Pull Request

None

Doc Impact

None

Size

None

External issue ID

None

External issue ID

None

Components

Priority

Major
Configure