I tried implementing async query using java-driver-async-queries. I am modifying a List within the FutureCallback but seems its not working -
List<Product> products = new ArrayList<Product>();
for (// iterating over a Map) {
key = entry.getKey();
String query = "SELECT id,desc,category FROM products where id=?";
ResultSetFuture future = session.executeAsync(query, key);
Futures.addCallback(future,
new FutureCallback<ResultSet>() {
@Override public void onSuccess(ResultSet result) {
Row row = result.one();
if (row != null) {
Product product = new Product();
product.setId(row.getString("id"));
product.setDesc(row.getString("desc"));
product.setCategory(row.getString("category"));
products.add(product);
}
}
@Override public void onFailure(Throwable t) {
// log error
}
},
MoreExecutors.sameThreadExecutor()
);
}
System.out.println("Product List : " + products); // Not printing correct values. Sometimes print blank
Is there any other way?
Based on Mikhail Baksheev answer I implemented and now getting proper result.
Just a twist. There is some extra logic i need to implement. I am wondering if I can use List<MyClass>
instead of List<ResultSetFuture>
and MyClass as -
public class MyClass {
private Integer productCount;
private Integer stockCount;
private ResultSetFuture result;
}
Then while iterating set FutureList
as -
ResultSetFuture result = session.executeAsync(query, key.get());
MyClass allResult = new MyClass();
allResult.setInCount(inCount);
allResult.setResult(result);
allResult.setSohCount(values.size() - inCount);
futuresList.add(allResult);
As @RussS mentioned, the code is not waiting all futures are completed.
There are many ways to synchronize async code. For example, using CountDownLatch:
EDIT: Also please use separte thread for callbacks and use concurrent collection for products.
Another way is to collect all futures in a list and wait all results as a single future with guava's Futures.allAsList, e.g:
EDIT 2
Technically yes, but you can't pass
List<MyClass>
inFutures.allAsList
in this case orMyClass
should implementListenableFuture
interface