Set timeout on thread execution and save return value

Asked

Viewed 673 times

2

Hello,

I have a web service, with backend in java 7. At some point, the backend makes a broadcast RPC call to N servers that are listening. Except that there is no predefined timeout in the call, I have no way to control the response time of N servers. I do not have access to the source code of N servers.

result = RPC.call(params, liveAddresses, conf);

The proposed solution was to convert the code to multi-threading, creating N threads. Each one is responsible for calling 1 address (server). If you follow the previous strategy:

It is possible in java to launch multiple threads with a maximum wait time each one ends. Getting the main thread the results of all threads ?

I accept ideas for other strategies to follow.

Thank you.

1 answer

2


An alternative would be the use of Executorservice

Basic Example:

Rpcresult.class:

public class RpcResult {

  private int clientId;
  private String response;

  // getters and setters...
}

Rpcexecutor.class:

public class RpcExecutor implements Callable<RpcResult>{

  private int clientId;

  public RpcExecutor(int clientId) {
    this.clientId = clientId;
  }

  public RpcResult call() throws Exception {    
    RpcResult result = new RpcResult();
    result.setClientId(clientId);
    result.setResponse("Resposta do cliente: " + clientId);

    return result;
  }

}

Execution:

ExecutorService executor = Executors.newFixedThreadPool(3);             
List<Callable<RpcResult>> list = new ArrayList<Callable<RpcResult>>();

for (int i = 1; i <= 3; i++) {
  list.add(new RpcExecutor(i));        
}

// 3 segundos de timeout
List<Future<RpcResult>> future = executor.invokeAll(list, 3L, TimeUnit.SECONDS);

for(Future<RpcResult> f : future) {           
  try {
    if (!f.isCancelled()) {
      RpcResult result = f.get();
      System.out.println(result.getClientId());
      System.out.println(result.getResponse());
    }
  } catch (InterruptedException e) {
    e.printStackTrace();
  } catch (ExecutionException e) {
    e.printStackTrace();
  }      
};

executor.shutdown();

To simulate the timeout of a client just add a Thread.Sleep() in the call() method of the Rpcexecutor class:

public RpcResult call() throws Exception {
    if (clientId == 2)
        Thread.sleep(15000);

    RpcResult result = new RpcResult();
    result.setClientId(clientId);
    result.setResponse("Resposta do cliente: " + clientId);

    return result;
}

EDIT


According to the new information related to the current project structure, this solution would not have scalability.

If you keep in mind that your application will never have many users, ok, go for the simplest solution. Now, if your application needs to scale, this could be one of the alternatives(simplified model):

Async Arch

  • Thanks for the answer. I forgot to say in the question that it is Java7. The Future stream I think is java 8. The biggest problem I have is not having access to the source code of the call() method. But I can use executor logic to call. invokeall can I set timeout ? By the way another issue that disturbs me, We are talking about a code of a Servlet, create N threads for each client can not create performance problem?

  • @user2989745 1 - Regarding the stream, just use a "for" in Java7, edit the answer. 2 - You can set the timeout of invokeAll. 3 - Since it is a web application, this solution is not very scalable. Suppose you have to consult 30 clients and you start one thread per client (30 threads per requests), then if your application gets 100 requests, it would be 100 * 30 threads open. I would go to an asynchronous solution requesting these queries for another application and the client could receive the reply by websocket...

  • Thank you! Yes I thought so, I wanted another opinion. Can you deepen your structure ? What would you gain from the asynchronous ? The action is triggered by a click on a button on the front end. I don’t know how to better control RPC response time....

  • @user2989745 What you get with an asynchronous solution is that you don’t secure a request on your server waiting for answers from third-party services that you don’t know how long they will respond to. I updated my answer to give you an idea of what it would be like.

  • Yeah, I see where the asynchronous can help. I get your idea, and it sounds like a good idea. I will study Websockets better, to see how it fits. But yes, interesting idea, thanks for the explanation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.