I have the following code which connects to a server, sends a request, then returns the response.
The problem is that if the client can't connect to the server, the program never progresses past this section
PayLoad payLoadFromServer = client.sendRequest();
I am just wondering what the best approach is to prevent the program from freezing, i.e. I want to timeout after say 5 seconds if the client can't connect, and be able to handle that gracefully in the program. Note I can't edit the Client class.
public PayLoad queryServer() {
try (final Client client = new Client("127.0.0.1", "8080")) {
PayLoad payLoadFromServer = client.sendRequest();
return payLoadFromServer;
}
}
Many thanks!
I tried to give it a very quick try. Create a wrapper object for your client class and make this new object runnable.
public class ClientWrapper implements Runnable {
private final String ip;
private final String port;
private Client client;
Lock lock = new ReentrantLock();
/**
* Creates a new instance of ClientWrapper.
*
* @param ip
* @param port
*/
public ClientWrapper(String ip, String port) {
this.ip = ip;
this.port = port;
}
public Lock getLock() {
return lock;
}
/**
* {@inheritDoc}
*/
@Override
public void run() {
lock.lock();
client = new Client(ip, port);
lock.unlock();
}
//create a method to expose client or its methods.
}
Now use an instance of this object as a thread like below.
import java.util.concurrent.TimeUnit;
/**
* @author rbhatt
*/
public class ClientCaller {
public static void main(String args[]) throws InterruptedException {
ClientWrapper clientWrapper = new ClientWrapper("127.0.0.1", "8080");
Thread t = new Thread(clientWrapper);
t.start();
boolean ret = clientWrapper.getLock().tryLock(250, TimeUnit.MILLISECONDS);
if (ret == false) {
System.out.println("can not acquire lock in 250 milliseconds, kill the thread.");
t.interrupt();
} else {
System.out.println("acquired lock in 250 milliseconds,release lock obtain client!");
clientWrapper.getLock().unlock();
}
}
}
as you can see, you can control your timeout in the caller, and we fail to obtain a lock, kill the client wrapper thread. I have used interrupt, you can use a volatile
variable. You can also use a executor service
and thread pools
etc.
Note: i have written this code just as an illustration about the idea, one can improve the code in many different ways.