0

I am relatively new to Cassandra, I am trying to retrieve data using prepared statement executed via an Executor Pool. Looks like the data I am receiving is not consistent.

I have this user_connections table, where user_id is the row key, friends_id list as a set column. I have this another table, friends_info table, where friend_id is the row key and all other information as columns.

When am trying to retrieve friends list for user AA, I am retrieving the friends list BBB, CCC, DDD. Which is perfectly fine.

When am trying to retrieve BBB, CCC, DDD via an executor pool using prepared statement. Data is inconsistent. Some times all three records are BBB, Some times all three records are, Some times two records are BBB and one is CCC etc...

I have provided the methods and relevant classes that I am using, can you please help me with this. I know prepared statement is thread safe and expected to work as expected.

public Set<User> listUserConnections(String userId) {
    Session session = client.getSession();

    Set<String> listUserConnectionIds = listUserConnections(userId, session);

    if (listUserConnectionIds.size() == 0)
        return new HashSet<User>();



    Set<User> listConnectionUserDetails = retrieveUserConnectionProfileInfo(
            listUserConnectionIds, session);
    return listConnectionUserDetails;

}



private Set<User> retrieveUserConnectionProfileInfo(Set<String> listUserConnectionIds,
        Session session) {


    Set<Callable<User>> callables = new HashSet<Callable<User>>();


     for(String key:listUserConnectionIds){



        logger.info("about to add callable" + key);

        Callable<User> callable = new QueryTask(key);

        callables.add(callable);

    }
    // invoke in parallel
    List<Future<User>> futures;
    Set<User> users = new HashSet<User>();

    // TODO Revisit this
    ExecutorService executorPool = Executors.newFixedThreadPool(100);

    try {
        futures = executorPool.invokeAll(callables);
        for (Future<User> f : futures) {

            User user = f.get();
            users.add(user);

            logger.info("User from future"+user.getUserId());

        }
    } catch (ExecutionException e) {
        logger.error("Error in retrieving the stores in parallel ", e);
    } catch (InterruptedException e) {
        logger.error("Error in retrieving the stores in parallel as it was interrupted ", e);
    } finally {
        executorPool.shutdown();
    }

    return users;
}

//Executor Pool Class

class QueryTask implements Callable<User> {

    private String userName;

    // final PreparedStatement statement =
    // client.getSession().prepare(QueryConstants.GET_ALL_STORE_BRANDS);

    QueryTask(String name) {
        this.userName = name;

    }

    @Override
    public User call() throws Exception {
        // -------------I am seeing the userName is correct------------- for example BBB
        logger.info("inside call processing queries for " + userName);

        //------------This is a prepared statement, userPreparedStatement.getbStUserInfo()
        BoundStatement bStUserInfo = userPreparedStatement.getbStUserInfo();
        bStUserInfo.bind(userName);
        Session session = client.getSession();
        ResultSet rs = session.execute(bStUserInfo);

        User user = new User();

        Iterator<Row> rowIterator = rs.iterator();
        while (rowIterator.hasNext())
        {
        Row row = rowIterator.next();

        //-------This user id is not right 
        logger.info("Inside the callable after retrieval"+row.getString(TableConstants.Users.COLUMN_NAME_USER_ID));
        user.setUserId(row.getString(TableConstants.Users.COLUMN_NAME_USER_ID));



        return user;
        }

        logger.info("outside the while loop");
        return user;

    }

}
Maxim
  • 9,701
  • 5
  • 60
  • 108
fsheriff
  • 11
  • 2
  • I don't see where you `new` your `BoundStatement` instances. – Ralf Apr 11 '16 at 07:19
  • 2
    As a side note, the driver already gives you an async API so you can get rid of almost all QueryTask/Executor code and focus on your test. – Alex Popescu Apr 11 '16 at 07:41

1 Answers1

0

Thank you so much @Ralf and Alex Popescu for getting back to me on this. Datastax had a documentation that dives deep on how the Aync calls work.

@ Alex Popescu. Thanks I tried their aync calls and it worked fine for me.

fsheriff
  • 11
  • 2