Skip to content

Commit 06e064b

Browse files
committed
[grid] delay the newsessionqueue response
1 parent b0464e1 commit 06e064b

19 files changed

+99
-7
lines changed

java/src/org/openqa/selenium/grid/commands/Hub.java

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ protected Handlers createHandlers(Config config) {
144144
distributorOptions.getSlotMatcher(),
145145
newSessionRequestOptions.getSessionRequestTimeoutPeriod(),
146146
newSessionRequestOptions.getSessionRequestTimeout(),
147+
newSessionRequestOptions.getMaximumResponseDelay(),
147148
secret,
148149
newSessionRequestOptions.getBatchSize());
149150
handler.addHandler(queue);

java/src/org/openqa/selenium/grid/commands/Standalone.java

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ protected Handlers createHandlers(Config config) {
150150
distributorOptions.getSlotMatcher(),
151151
newSessionRequestOptions.getSessionRequestTimeoutPeriod(),
152152
newSessionRequestOptions.getSessionRequestTimeout(),
153+
newSessionRequestOptions.getMaximumResponseDelay(),
153154
registrationSecret,
154155
newSessionRequestOptions.getBatchSize());
155156
combinedHandler.addHandler(queue);

java/src/org/openqa/selenium/grid/sessionqueue/config/NewSessionQueueOptions.java

+10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
public class NewSessionQueueOptions {
3636

3737
static final String SESSION_QUEUE_SECTION = "sessionqueue";
38+
static final int MAXIMUM_RESPONSE_DELAY = 8;
3839
static final int DEFAULT_REQUEST_TIMEOUT = 300;
3940
static final int DEFAULT_REQUEST_TIMEOUT_PERIOD = 10;
4041
static final int DEFAULT_RETRY_INTERVAL = 15;
@@ -89,6 +90,15 @@ public URI getSessionQueueUri() {
8990
}
9091
}
9192

93+
public Duration getMaximumResponseDelay() {
94+
int timeout =
95+
config
96+
.getInt(SESSION_QUEUE_SECTION, "maximum-response-delay")
97+
.orElse(MAXIMUM_RESPONSE_DELAY);
98+
99+
return Duration.ofSeconds(timeout);
100+
}
101+
92102
public Duration getSessionRequestTimeout() {
93103
// If the user sets 0 or less, we default to 1s.
94104
int timeout =

java/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java

+48-7
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public class LocalNewSessionQueue extends NewSessionQueue implements Closeable {
9696
private static final String NAME = "Local New Session Queue";
9797
private final SlotMatcher slotMatcher;
9898
private final Duration requestTimeout;
99+
private final Duration maximumResponseDelay;
99100
private final int batchSize;
100101
private final Map<RequestId, Data> requests;
101102
private final Map<RequestId, TraceContext> contexts;
@@ -115,6 +116,7 @@ public LocalNewSessionQueue(
115116
SlotMatcher slotMatcher,
116117
Duration requestTimeoutCheck,
117118
Duration requestTimeout,
119+
Duration maximumResponseDelay,
118120
Secret registrationSecret,
119121
int batchSize) {
120122
super(tracer, registrationSecret);
@@ -123,6 +125,7 @@ public LocalNewSessionQueue(
123125
Require.nonNegative("Retry period", requestTimeoutCheck);
124126

125127
this.requestTimeout = Require.positive("Request timeout", requestTimeout);
128+
this.maximumResponseDelay = Require.positive("Maximum response delay", maximumResponseDelay);
126129

127130
this.requests = new ConcurrentHashMap<>();
128131
this.queue = new ConcurrentLinkedDeque<>();
@@ -152,6 +155,7 @@ public static NewSessionQueue create(Config config) {
152155
slotMatcher,
153156
newSessionQueueOptions.getSessionRequestTimeoutPeriod(),
154157
newSessionQueueOptions.getSessionRequestTimeout(),
158+
newSessionQueueOptions.getMaximumResponseDelay(),
155159
secretOptions.getRegistrationSecret(),
156160
newSessionQueueOptions.getBatchSize());
157161
}
@@ -234,7 +238,9 @@ public HttpResponse addToQueue(SessionRequest request) {
234238
}
235239

236240
Lock writeLock = this.lock.writeLock();
237-
writeLock.lock();
241+
if (!writeLock.tryLock()) {
242+
writeLock.lock();
243+
}
238244
try {
239245
requests.remove(request.getRequestId());
240246
queue.remove(request);
@@ -268,7 +274,9 @@ Data injectIntoQueue(SessionRequest request) {
268274
Data data = new Data(request.getEnqueued());
269275

270276
Lock writeLock = lock.writeLock();
271-
writeLock.lock();
277+
if (!writeLock.tryLock()) {
278+
writeLock.lock();
279+
}
272280
try {
273281
requests.put(request.getRequestId(), data);
274282
queue.addLast(request);
@@ -288,7 +296,9 @@ public boolean retryAddToQueue(SessionRequest request) {
288296
contexts.getOrDefault(request.getRequestId(), tracer.getCurrentContext());
289297
try (Span ignored = context.createSpan("sessionqueue.retry")) {
290298
Lock writeLock = lock.writeLock();
291-
writeLock.lock();
299+
if (!writeLock.tryLock()) {
300+
writeLock.lock();
301+
}
292302
try {
293303
if (!requests.containsKey(request.getRequestId())) {
294304
return false;
@@ -319,7 +329,9 @@ public Optional<SessionRequest> remove(RequestId reqId) {
319329
Require.nonNull("Request ID", reqId);
320330

321331
Lock writeLock = lock.writeLock();
322-
writeLock.lock();
332+
if (!writeLock.tryLock()) {
333+
writeLock.lock();
334+
}
323335
try {
324336
Iterator<SessionRequest> iterator = queue.iterator();
325337
while (iterator.hasNext()) {
@@ -340,6 +352,29 @@ public Optional<SessionRequest> remove(RequestId reqId) {
340352
public List<SessionRequest> getNextAvailable(Map<Capabilities, Long> stereotypes) {
341353
Require.nonNull("Stereotypes", stereotypes);
342354

355+
// use nano time to avoid issues with a jumping clock e.g. on WSL2 or due to time-sync
356+
long started = System.nanoTime();
357+
// delay the response to avoid heavy polling via http
358+
while (maximumResponseDelay.toNanos() > System.nanoTime() - started) {
359+
Lock readLock = lock.readLock();
360+
readLock.lock();
361+
362+
try {
363+
if (!queue.isEmpty()) {
364+
break;
365+
}
366+
} finally {
367+
readLock.unlock();
368+
}
369+
370+
try {
371+
Thread.sleep(10);
372+
} catch (InterruptedException ex) {
373+
Thread.currentThread().interrupt();
374+
break;
375+
}
376+
}
377+
343378
Predicate<Capabilities> matchesStereotype =
344379
caps ->
345380
stereotypes.entrySet().stream()
@@ -355,7 +390,9 @@ public List<SessionRequest> getNextAvailable(Map<Capabilities, Long> stereotypes
355390
});
356391

357392
Lock writeLock = lock.writeLock();
358-
writeLock.lock();
393+
if (!writeLock.tryLock()) {
394+
writeLock.lock();
395+
}
359396
try {
360397
List<SessionRequest> availableRequests =
361398
queue.stream()
@@ -381,7 +418,9 @@ public boolean complete(
381418
try (Span ignored = context.createSpan("sessionqueue.completed")) {
382419
Data data;
383420
Lock writeLock = lock.writeLock();
384-
writeLock.lock();
421+
if (!writeLock.tryLock()) {
422+
writeLock.lock();
423+
}
385424
try {
386425
data = requests.remove(reqId);
387426
queue.removeIf(req -> reqId.equals(req.getRequestId()));
@@ -401,7 +440,9 @@ public boolean complete(
401440
@Override
402441
public int clearQueue() {
403442
Lock writeLock = lock.writeLock();
404-
writeLock.lock();
443+
if (!writeLock.tryLock()) {
444+
writeLock.lock();
445+
}
405446

406447
try {
407448
int size = queue.size();

java/test/org/openqa/selenium/grid/distributor/AddingNodesTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public void setUpDistributor() throws MalformedURLException {
109109
new DefaultSlotMatcher(),
110110
Duration.ofSeconds(2),
111111
Duration.ofSeconds(2),
112+
Duration.ofSeconds(1),
112113
registrationSecret,
113114
5);
114115

java/test/org/openqa/selenium/grid/distributor/DistributorDrainingTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void drainedNodeDoesNotShutDownIfNotEmpty() throws InterruptedException {
5454
new DefaultSlotMatcher(),
5555
Duration.ofSeconds(2),
5656
Duration.ofSeconds(2),
57+
Duration.ofSeconds(1),
5758
registrationSecret,
5859
5);
5960
LocalNode node =
@@ -106,6 +107,7 @@ void drainedNodeShutsDownAfterSessionsFinish() throws InterruptedException {
106107
new DefaultSlotMatcher(),
107108
Duration.ofSeconds(2),
108109
Duration.ofSeconds(2),
110+
Duration.ofSeconds(1),
109111
registrationSecret,
110112
5);
111113
LocalNode node =
@@ -182,6 +184,7 @@ void testDrainedNodeShutsDownOnceEmpty() throws InterruptedException {
182184
new DefaultSlotMatcher(),
183185
Duration.ofSeconds(2),
184186
Duration.ofSeconds(2),
187+
Duration.ofSeconds(1),
185188
registrationSecret,
186189
5);
187190
LocalNode node =
@@ -234,6 +237,7 @@ void drainingNodeDoesNotAcceptNewSessions() {
234237
new DefaultSlotMatcher(),
235238
Duration.ofSeconds(2),
236239
Duration.ofSeconds(2),
240+
Duration.ofSeconds(1),
237241
registrationSecret,
238242
5);
239243
LocalNode node =

java/test/org/openqa/selenium/grid/distributor/DistributorNodeAvailabilityTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ void shouldBeAbleToRemoveANode() throws MalformedURLException {
9797
new DefaultSlotMatcher(),
9898
Duration.ofSeconds(2),
9999
Duration.ofSeconds(2),
100+
Duration.ofSeconds(1),
100101
registrationSecret,
101102
5);
102103

@@ -147,6 +148,7 @@ void shouldIncludeHostsThatAreUpInHostList() {
147148
new DefaultSlotMatcher(),
148149
Duration.ofSeconds(2),
149150
Duration.ofSeconds(2),
151+
Duration.ofSeconds(1),
150152
registrationSecret,
151153
5);
152154
handler.addHandler(sessions);
@@ -219,6 +221,7 @@ void shouldNotRemoveNodeWhoseHealthCheckPassesBeforeThreshold() throws Interrupt
219221
new DefaultSlotMatcher(),
220222
Duration.ofSeconds(2),
221223
Duration.ofSeconds(2),
224+
Duration.ofSeconds(1),
222225
registrationSecret,
223226
5);
224227

@@ -281,6 +284,7 @@ void shouldReturnNodesThatWereDownToPoolOfNodesOnceTheyMarkTheirHealthCheckPasse
281284
new DefaultSlotMatcher(),
282285
Duration.ofSeconds(2),
283286
Duration.ofSeconds(2),
287+
Duration.ofSeconds(1),
284288
registrationSecret,
285289
5);
286290

@@ -338,6 +342,7 @@ void shouldBeAbleToAddANodeAndCreateASession() {
338342
new DefaultSlotMatcher(),
339343
Duration.ofSeconds(2),
340344
Duration.ofSeconds(2),
345+
Duration.ofSeconds(1),
341346
registrationSecret,
342347
5);
343348
LocalNode node =

java/test/org/openqa/selenium/grid/distributor/DistributorTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void creatingASessionAddsItToTheSessionMap() {
8484
new DefaultSlotMatcher(),
8585
Duration.ofSeconds(2),
8686
Duration.ofSeconds(2),
87+
Duration.ofSeconds(1),
8788
registrationSecret,
8889
5);
8990

@@ -134,6 +135,7 @@ void shouldReleaseSlotOnceSessionEnds() {
134135
new DefaultSlotMatcher(),
135136
Duration.ofSeconds(2),
136137
Duration.ofSeconds(2),
138+
Duration.ofSeconds(1),
137139
registrationSecret,
138140
5);
139141

@@ -203,6 +205,7 @@ void shouldNotStartASessionIfTheCapabilitiesAreNotSupported() {
203205
new DefaultSlotMatcher(),
204206
Duration.ofSeconds(2),
205207
Duration.ofSeconds(2),
208+
Duration.ofSeconds(1),
206209
registrationSecret,
207210
5);
208211
handler.addHandler(sessions);
@@ -243,6 +246,7 @@ void attemptingToStartASessionWhichFailsMarksAsTheSlotAsAvailable() {
243246
new DefaultSlotMatcher(),
244247
Duration.ofSeconds(2),
245248
Duration.ofSeconds(2),
249+
Duration.ofSeconds(1),
246250
registrationSecret,
247251
5);
248252

java/test/org/openqa/selenium/grid/distributor/DistributorTestBase.java

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ public void setUp() throws URISyntaxException {
106106
new DefaultSlotMatcher(),
107107
Duration.ofSeconds(2),
108108
Duration.ofSeconds(2),
109+
Duration.ofSeconds(1),
109110
registrationSecret,
110111
5);
111112

java/test/org/openqa/selenium/grid/distributor/SessionSchedulingTest.java

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ void theMostLightlyLoadedNodeIsSelectedFirst() {
6666
new DefaultSlotMatcher(),
6767
Duration.ofSeconds(2),
6868
Duration.ofSeconds(2),
69+
Duration.ofSeconds(1),
6970
registrationSecret,
7071
5);
7172

@@ -121,6 +122,7 @@ void shouldUseLastSessionCreatedTimeAsTieBreaker() {
121122
new DefaultSlotMatcher(),
122123
Duration.ofSeconds(2),
123124
Duration.ofSeconds(2),
125+
Duration.ofSeconds(1),
124126
registrationSecret,
125127
5);
126128
Node leastRecent = createNode(caps, 5, 0);
@@ -192,6 +194,7 @@ void shouldNotScheduleAJobIfAllSlotsAreBeingUsed() {
192194
new DefaultSlotMatcher(),
193195
Duration.ofSeconds(2),
194196
Duration.ofSeconds(2),
197+
Duration.ofSeconds(1),
195198
registrationSecret,
196199
5);
197200

@@ -247,6 +250,7 @@ void shouldPrioritizeHostsWithTheMostSlotsAvailableForASessionType() {
247250
new DefaultSlotMatcher(),
248251
Duration.ofSeconds(2),
249252
Duration.ofSeconds(2),
253+
Duration.ofSeconds(1),
250254
registrationSecret,
251255
5);
252256

java/test/org/openqa/selenium/grid/distributor/local/LocalDistributorTest.java

+7
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ void testAddNodeToDistributor() {
118118
new DefaultSlotMatcher(),
119119
Duration.ofSeconds(2),
120120
Duration.ofSeconds(2),
121+
Duration.ofSeconds(1),
121122
registrationSecret,
122123
5);
123124
Distributor distributor =
@@ -157,6 +158,7 @@ void testRemoveNodeFromDistributor() {
157158
new DefaultSlotMatcher(),
158159
Duration.ofSeconds(2),
159160
Duration.ofSeconds(2),
161+
Duration.ofSeconds(1),
160162
registrationSecret,
161163
5);
162164
Distributor distributor =
@@ -195,6 +197,7 @@ void testAddSameNodeTwice() {
195197
new DefaultSlotMatcher(),
196198
Duration.ofSeconds(2),
197199
Duration.ofSeconds(2),
200+
Duration.ofSeconds(1),
198201
registrationSecret,
199202
5);
200203
Distributor distributor =
@@ -228,6 +231,7 @@ void shouldBeAbleToAddMultipleSessionsConcurrently() throws Exception {
228231
new DefaultSlotMatcher(),
229232
Duration.ofSeconds(2),
230233
Duration.ofSeconds(2),
234+
Duration.ofSeconds(1),
231235
registrationSecret,
232236
5);
233237

@@ -321,6 +325,7 @@ void testDrainNodeFromDistributor() {
321325
new DefaultSlotMatcher(),
322326
Duration.ofSeconds(2),
323327
Duration.ofSeconds(2),
328+
Duration.ofSeconds(1),
324329
registrationSecret,
325330
5);
326331
Distributor distributor =
@@ -366,6 +371,7 @@ void testDrainNodeFromNode() {
366371
new DefaultSlotMatcher(),
367372
Duration.ofSeconds(2),
368373
Duration.ofSeconds(2),
374+
Duration.ofSeconds(1),
369375
registrationSecret,
370376
5);
371377
Distributor distributor =
@@ -396,6 +402,7 @@ void slowStartingNodesShouldNotCauseReservationsToBeSerialized() {
396402
new DefaultSlotMatcher(),
397403
Duration.ofSeconds(2),
398404
Duration.ofSeconds(2),
405+
Duration.ofSeconds(1),
399406
registrationSecret,
400407
5);
401408

java/test/org/openqa/selenium/grid/graphql/GraphqlHandlerTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public void setupGrid() {
121121
new DefaultSlotMatcher(),
122122
Duration.ofSeconds(2),
123123
Duration.ofSeconds(2),
124+
Duration.ofSeconds(1),
124125
registrationSecret,
125126
5);
126127

0 commit comments

Comments
 (0)