6

I need to execute a ping webservice to check if I have connection to the endpoint and the webservice server is all fine.

It's kinda dumb but I have to call a webservice for this. The problem is that when I call the stub.ping(request) and I dont have connection it keeps trying to execute this code for like a minute... and then returns false.

Any way to make this timeout after 1 second if it cannot ping?

public boolean ping() {
        try {
            PingServiceStub stub = new PingServiceStub(soapGWEndpoint);
            ReqPing request = new ReqPing();

            UserInfo userInfo = new UserInfo();
            userInfo.setName(soapGWUser);
            userInfo.setPassword(soapGWPassword);
            ApplicationInfo applicationInfo = new ApplicationInfo();
            applicationInfo.setConfigurationName(soapGWAppName);

            stub.ping(request);

            return true;
        } catch (RemoteException | PingFault e) {
            return false;
        }
    }
user11341081
  • 199
  • 7
  • https://stackoverflow.com/questions/10437890/what-is-the-best-way-to-handle-an-executionexception – Christophe Roussy May 13 '19 at 15:11
  • @Bentaye this needs to be executed before I make another ws call. I need to ping -> if all ok make other request, otherwise dont do anything. I need to get the ping information within 1 second – user11341081 May 13 '19 at 15:12
  • 1
    Possible duplicate of [What is the best way to handle an ExecutionException?](https://stackoverflow.com/questions/10437890/what-is-the-best-way-to-handle-an-executionexception) –  May 13 '19 at 15:15
  • What you're looking for is a Watchdog or Timeout Observer, you can find a really well explained example about it here: http://www.java2s.com/Code/Java/Development-Class/TimeoutObserver.htm Basically you can reuse the code that is in that example and just implement the interface TimeoutObserver with the specific thing that you would like to do in case of Timeout. – Daniel Campos Olivares May 13 '19 at 15:18

2 Answers2

3

You could use something like the TimeLimiter from the Google Guava library. This allows you to wrap a callable in an operation that you can call with Timeout. If the callable does not complete the operation in time, it will throw a TimeoutException which you can catch and return false after one second.

As an example:

TimeLimiter timeLimiter = new SimpleTimeLimiter();
try {
  String result = timeLimiter.callWithTimeout(
                () -> callToPing(), 1, TimeUnit.SECONDS);
  return true // Or something based on result
} catch (TimeoutException e) {
  return false
}
Blokje5
  • 4,763
  • 1
  • 20
  • 37
2

You could execute your task asynchronously as runnable in a threadpool using ExecutorService :

ExecutorService executorService = Executors.newCachedThreadPool();

Runnable runnable = () -> {
      stub.ping(request);
};

Future<?> submit = executorService.submit(runnable);

try {
     submit.get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
     e.printStackTrace();
} catch (TimeoutException e) {
     System.out.println("Task was being executed for more than 1 second");
     //submit.cancel(true); to cancel this task and if it is responsive to interruption the task will finish
}

A TimeoutException will be thrown when task is being executed for more than the time you specified in get method. Note that the Future::get is a blocking operation.

Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63