[java] An attempt to fix timeouts in quit operation caused by missing response
import java.io.IOException;
import java.net.ConnectException;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* A specialized {@link HttpCommandExecutor} that will use a {@link DriverService} that lives
@@ -79,6 +83,8 @@ public Response execute(Command command) throws IOException {
service.start();
}
+ if (DriverCommand.QUIT.equals(command.getName())) {
+ CompletableFuture<Response> commandComplete = CompletableFuture.supplyAsync(() -> {
try {
return super.execute(command);
} catch (Throwable t) {
@@ -90,9 +96,41 @@ public Response execute(Command command) throws IOException {
}
Throwables.throwIfUnchecked(t);
throw new WebDriverException(t);
- } finally {
- if (DriverCommand.QUIT.equals(command.getName())) {
+ }
+ });
+
+ CompletableFuture<Response> processFinished = CompletableFuture.supplyAsync(() -> {
+ service.process.waitFor(service.getTimeout().toMillis());
+ return null;
+ });
+
+ try {
+ Response response = (Response) CompletableFuture.anyOf(commandComplete, processFinished)
+ .get(service.getTimeout().toMillis() * 2, TimeUnit.MILLISECONDS);
+ if (response != null) {
service.stop();
+ return response;
+ } else {
+ return null;
+ }
+ } catch (ExecutionException | TimeoutException e) {
+ throw new WebDriverException("Timed out waiting for driver server to stop.", e);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new WebDriverException("Timed out waiting for driver server to stop.", e);
+ }
+ } else {
+ try {
+ return super.execute(command);
+ } catch (Throwable t) {
+ Throwable rootCause = Throwables.getRootCause(t);
+ if (rootCause instanceof ConnectException &&
+ "Connection refused".equals(rootCause.getMessage()) &&
+ !service.isRunning()) {
+ throw new WebDriverException("The driver server has unexpectedly died!", t);
+ }
+ Throwables.throwIfUnchecked(t);
+ throw new WebDriverException(t);
}
}
}
