Skip to content

Commit ad1f4e6

Browse files
Mahoneylukeis
authored andcommitted
Reduces time wasted in when using a native driver
UrlChecker normally adds 1 second to any test that creates and destroys a DriverService such as the ChromeDriver since the initial poll on both startup and shutdown nearly always fails and the time between polls (500 millis) is high. This switches to using an initially small but exponentially increasing poll time in order to waste much less time waiting for nothing. Closes SeleniumHQ#1334 Signed-off-by: Luke Inman-Semerau <luke.semerau@gmail.com>
1 parent 6d8c621 commit ad1f4e6

File tree

2 files changed

+126
-3
lines changed

2 files changed

+126
-3
lines changed

java/client/src/org/openqa/selenium/net/UrlChecker.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public class UrlChecker {
4848

4949
private static final int CONNECT_TIMEOUT_MS = 500;
5050
private static final int READ_TIMEOUT_MS = 1000;
51-
private static final long POLL_INTERVAL_MS = 500;
51+
private static final long MAX_POLL_INTERVAL_MS = 320;
52+
private static final long MIN_POLL_INTERVAL_MS = 10;
5253

5354
private static final AtomicInteger THREAD_COUNTER = new AtomicInteger(1);
5455
private static final ExecutorService THREAD_POOL = Executors
@@ -80,6 +81,7 @@ public void waitUntilAvailable(long timeout, TimeUnit unit, final URL... urls)
8081
public Void call() throws InterruptedException {
8182
HttpURLConnection connection = null;
8283

84+
long sleepMillis = MIN_POLL_INTERVAL_MS;
8385
while (true) {
8486
for (URL url : urls) {
8587
try {
@@ -96,7 +98,8 @@ public Void call() throws InterruptedException {
9698
}
9799
}
98100
}
99-
MILLISECONDS.sleep(POLL_INTERVAL_MS);
101+
MILLISECONDS.sleep(sleepMillis);
102+
sleepMillis = (sleepMillis >= MAX_POLL_INTERVAL_MS) ? sleepMillis : sleepMillis * 2;
100103
}
101104
}
102105
}, timeout, unit, true);
@@ -118,6 +121,7 @@ public void waitUntilUnavailable(long timeout, TimeUnit unit, final URL url)
118121
public Void call() throws InterruptedException {
119122
HttpURLConnection connection = null;
120123

124+
long sleepMillis = MIN_POLL_INTERVAL_MS;
121125
while (true) {
122126
try {
123127
log.fine("Polling " + url);
@@ -133,7 +137,8 @@ public Void call() throws InterruptedException {
133137
}
134138
}
135139

136-
MILLISECONDS.sleep(POLL_INTERVAL_MS);
140+
MILLISECONDS.sleep(sleepMillis);
141+
sleepMillis = (sleepMillis >= MAX_POLL_INTERVAL_MS) ? sleepMillis : sleepMillis * 2;
137142
}
138143
}
139144
}, timeout, unit, true);
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.openqa.selenium.net;
18+
19+
import static java.lang.System.currentTimeMillis;
20+
import static org.hamcrest.Matchers.lessThan;
21+
import static org.junit.Assert.assertThat;
22+
import static org.openqa.selenium.net.PortProber.findFreePort;
23+
24+
import org.junit.After;
25+
import org.junit.Test;
26+
import org.junit.runner.RunWith;
27+
import org.junit.runners.JUnit4;
28+
import org.seleniumhq.jetty9.server.Handler;
29+
import org.seleniumhq.jetty9.server.HttpConnection;
30+
import org.seleniumhq.jetty9.server.Request;
31+
import org.seleniumhq.jetty9.server.Server;
32+
import org.seleniumhq.jetty9.server.ServerConnector;
33+
import org.seleniumhq.jetty9.server.handler.AbstractHandler;
34+
35+
import java.io.IOException;
36+
import java.net.URL;
37+
import java.util.concurrent.Callable;
38+
import java.util.concurrent.ExecutorService;
39+
import java.util.concurrent.Executors;
40+
import java.util.concurrent.TimeUnit;
41+
42+
import javax.servlet.ServletException;
43+
import javax.servlet.http.HttpServletRequest;
44+
import javax.servlet.http.HttpServletResponse;
45+
46+
@RunWith(JUnit4.class)
47+
public class UrlCheckerTest {
48+
49+
private final UrlChecker urlChecker = new UrlChecker();
50+
int port = findFreePort();
51+
Server server = buildServer();
52+
53+
private Server buildServer() {
54+
Server server = new Server(port);
55+
server.setHandler(new AbstractHandler() {
56+
@Override
57+
public void handle(String s, Request request, HttpServletRequest httpServletRequest,
58+
HttpServletResponse httpServletResponse)
59+
throws IOException, ServletException {
60+
httpServletResponse.setStatus(200);
61+
httpServletResponse.getWriter().println("<h1>Working</h1>");
62+
request.setHandled(true);
63+
}
64+
});
65+
return server;
66+
}
67+
68+
ExecutorService executorService = Executors.newSingleThreadExecutor();
69+
70+
@Test
71+
public void testWaitUntilAvailableIsTimely() throws Exception {
72+
73+
executorService.submit(new Callable<Object>() {
74+
@Override
75+
public Object call() throws Exception {
76+
Thread.sleep(10L);
77+
server.start();
78+
return null;
79+
}
80+
});
81+
82+
long start = currentTimeMillis();
83+
urlChecker.waitUntilAvailable(10, TimeUnit.SECONDS, new URL("http://localhost:" + port + "/"));
84+
long elapsed = currentTimeMillis() - start;
85+
assertThat(elapsed, lessThan(450L));
86+
System.out.println(elapsed);
87+
}
88+
89+
@Test
90+
public void testWaitUntilUnavailableIsTimely() throws Exception {
91+
92+
server.start();
93+
urlChecker.waitUntilAvailable(10, TimeUnit.SECONDS, new URL("http://localhost:" + port + "/"));
94+
95+
executorService.submit(new Callable<Object>() {
96+
@Override
97+
public Object call() throws Exception {
98+
Thread.sleep(10L);
99+
server.stop();
100+
return null;
101+
}
102+
});
103+
104+
long start = currentTimeMillis();
105+
urlChecker.waitUntilUnavailable(10, TimeUnit.SECONDS,
106+
new URL("http://localhost:" + port + "/"));
107+
long elapsed = currentTimeMillis() - start;
108+
assertThat(elapsed, lessThan(450L));
109+
System.out.println(elapsed);
110+
}
111+
112+
@After
113+
public void cleanup() throws Exception {
114+
server.stop();
115+
server.join();
116+
executorService.shutdown();
117+
}
118+
}

0 commit comments

Comments
 (0)