2

I need to get messages from a service in a given interval.

I make a request to my service, where I specify FROM date and TO date. But the service starts from the FROM date, and goes up to 2000 messages and then it returns me those 2000 messages, no more, even if the TO date is not reached.

So if I want to get all the messages, I have to check every response and if there are 2000 messages, then I need to make another request where I specify the FROM date as the date of the last message returned. And so on until I get to the TO date.

Let's say the method looks like this:

public void getMessages(Date from, Date to, Callback<List<Message>> onSuccess);

So I tried to write it like so:

List<Message> allMessages = new ArrayList<>();
getMessages(fromDate, toDate, messages -> {
   //save all the messages returned
   allMessages.addAll(messages);
   if(messages.size()==2000){
      //get the last message date
      Date nextDate = messages.get(messages.size() - 1).getDateTime();
      //query next messages
      getMessages(nextDate, to, onSuccess); //and here I am screwed in what to put in the onSuccess again...
   }
});

How to do it so it would continue certain number of steps, or stop when it finally reaches the TO date? I can even change the getMessages() method, but I get the data from HTTP request, so it needs to be done via Callback.

UPDATE: Thanks for all the answers, based on them I came up with a simple solution.

I created a method like this:

private void checkMessages(List<Message> messages, Date toDate, List<Message> allMessages) {
    // save all the messages returned
    allMessages.addAll(messages);
    if (messages.size() == 2000) {
      // get the last message date
      Date nextDate = messages.get(messages.size() - 1).getDateTime();
      // query next messages
      getMessages(nextDate, toDate,
          msgs -> checkMessages(msgs, toDate, allMessages));
    } else {
      // else we are finished
      messageTable.setMessages(allMessages);
    }
  }

and the I used this method in the callback:

List<Message> allMessages = new ArrayList<>();
getMessages(fromDate, toDate,
        messages -> checkMessages(messages, toDate, allMessages));

It's definitely not ideal, but it seems to be working.

ezpzlmnsqz1337
  • 394
  • 1
  • 5
  • 16

2 Answers2

0

How about this?

    List<Message> allMessages = new ArrayList<>();
    Callback<List<Message>> onSuccessCallback = messages -> {
           //save all the messages returned
           allMessages.addAll(messages);
           if(messages.size()==2000){
              //get the last message date
              Date nextDate = messages.get(messages.size() - 1).getDateTime();
              //query next messages
              getMessages(nextDate, toDate, onSuccessCallback);
           }
    };
    getMessages(fromDate, toDate, onSuccessCallback);
  • And how do I know when it ended so that I can start working with the allMessages? But it looks promising – ezpzlmnsqz1337 Sep 06 '18 at 15:50
  • ok I tried this, but I am getting: "The local variable onSuccessCallback may not have been initialized." inside the callback :( – ezpzlmnsqz1337 Sep 06 '18 at 16:00
  • Oh, you're right, take a look at [this solution](https://stackoverflow.com/questions/19429667/implement-recursive-lambda-function-using-java-8). – Jorge Valencia Sep 07 '18 at 15:06
0

Instead of a callback, you can have a Predicate with which you will decide whether or not you need to make another call..

I'm demonstrating async service call with a Thread here1. This may or may not work for you. It would be more helpful if you can show us how you invoke the callback once the service returns a response.

public void getMessages(Date from, Date to, Predicate<List<Message>> shouldMakeAnotherCall) {
    new Thread(() -> {
        List<Message> messages = //Call service
        if (shouldMakeAnotherCall.apply(messages)) {
            getMessages(from, to, shouldMakeAnotherCall);
        }   
    }).start();
}

Predicate<List<Message>> shouldMakeAnotherCall = listOfMessages -> listOfMessages.size() == 2000;

getMessages(from, to, shouldMakeAnotherCall);

1 This makes subsequent calls where each creates a new Thread and so is not a great one.

Thiyagu
  • 17,362
  • 5
  • 42
  • 79