Skip to content

Commit 3c113b3

Browse files
authored
Merge branch 'trunk' into renovate/io.lettuce-lettuce-core-6.x
2 parents 2fc15ce + 334cfaa commit 3c113b3

File tree

14 files changed

+414
-56
lines changed

14 files changed

+414
-56
lines changed

MODULE.bazel

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ bazel_dep(name = "rules_dotnet", version = "0.17.5")
2121
bazel_dep(name = "rules_java", version = "7.12.4")
2222
bazel_dep(name = "rules_jvm_external", version = "6.6")
2323
bazel_dep(name = "rules_nodejs", version = "6.3.2")
24-
bazel_dep(name = "rules_oci", version = "1.7.6")
24+
bazel_dep(name = "rules_oci", version = "1.8.0")
2525
bazel_dep(name = "rules_pkg", version = "0.10.1")
2626
bazel_dep(name = "rules_python", version = "0.33.0")
2727
bazel_dep(name = "rules_proto", version = "6.0.2")
@@ -173,14 +173,14 @@ maven.install(
173173
"com.github.spotbugs:spotbugs:4.8.6",
174174
"com.github.stephenc.jcip:jcip-annotations:1.0-1",
175175
"com.google.code.gson:gson:2.11.0",
176-
"com.google.guava:guava:33.3.1-jre",
176+
"com.google.guava:guava:33.4.0-jre",
177177
"com.google.auto:auto-common:1.2.2",
178178
"com.google.auto.service:auto-service:1.1.1",
179179
"com.google.auto.service:auto-service-annotations:1.1.1",
180180
"com.google.googlejavaformat:google-java-format:1.25.2:1.25.0",
181181
"com.graphql-java:graphql-java:22.3",
182182
"dev.failsafe:failsafe:3.3.2",
183-
"io.grpc:grpc-context:1.68.1",
183+
"io.grpc:grpc-context:1.69.0",
184184
"io.lettuce:lettuce-core:6.5.2.RELEASE",
185185
"io.netty:netty-buffer",
186186
"io.netty:netty-codec-http",

java/maven_install.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@
124124
},
125125
"com.google.errorprone:error_prone_annotations": {
126126
"shasums": {
127-
"jar": "f3fc8a3a0a4020706a373b00e7f57c2512dd26d1f83d28c7d38768f8682b231e",
128-
"sources": "2936e9b315d790d8a6364f0574bcec9c8b2d78688b317e1765c4a16f9ef80632"
127+
"jar": "77440e270b0bc9a249903c5a076c36a722c4886ca4f42675f2903a1c53ed61a5",
128+
"sources": "7e117e0931cb2cb4226372af336189b49edb79969d120ec958a6df0beacb0612"
129129
},
130-
"version": "2.28.0"
130+
"version": "2.36.0"
131131
},
132132
"com.google.googlejavaformat:google-java-format": {
133133
"shasums": {
@@ -145,10 +145,10 @@
145145
},
146146
"com.google.guava:guava": {
147147
"shasums": {
148-
"jar": "4bf0e2c5af8e4525c96e8fde17a4f7307f97f8478f11c4c8e35a0e3298ae4e90",
149-
"sources": "b7cbdad958b791f2a036abff7724570bf9836531c460966f8a3d0df8eaa1c21d"
148+
"jar": "b918c98a7e44dbe94ebd9fe3e40cddaadb5a93e6a78eb6008b42df237241e538",
149+
"sources": "55ef6603b6ab1f6e3ae810b127561650ed682eb5f3fb50a212a658a74087b457"
150150
},
151-
"version": "33.3.1-jre"
151+
"version": "33.4.0-jre"
152152
},
153153
"com.google.guava:listenablefuture": {
154154
"shasums": {
@@ -214,17 +214,17 @@
214214
},
215215
"io.grpc:grpc-api": {
216216
"shasums": {
217-
"jar": "d88d815e07fe58a7572dda5d2823485b61706564f289a1e74281705d50ac2d5b",
218-
"sources": "791d817c56f03690df499020479e23494b79ab6ed578f4f50285d83d45a1f35d"
217+
"jar": "ffa9af0f76fb08b4dbcade9dba9805af6b216980cafa0756b4d97b6029077506",
218+
"sources": "e175c53977b6899c7be5a2e2007f79996d46c5512e852975cb4af663ffd84db9"
219219
},
220-
"version": "1.68.1"
220+
"version": "1.69.0"
221221
},
222222
"io.grpc:grpc-context": {
223223
"shasums": {
224-
"jar": "1df4f0310a7e7836bc2948afa95105f5ee27b5d468488aded74e7ff620359076",
225-
"sources": "6f5941f8531f6eea4ff922d2019757d06dc5857327ff9b9858ace45c0cf0ef8b"
224+
"jar": "e682d036496d4429442955b615b931ee65486bd318d0ab13d9937d11cb36ffd5",
225+
"sources": "a2ac5373e3f1021ec3f936b7c994b5fb94b391a8db24333825a0c081163d9efd"
226226
},
227-
"version": "1.68.1"
227+
"version": "1.69.0"
228228
},
229229
"io.lettuce:lettuce-core": {
230230
"shasums": {

java/src/org/openqa/selenium/grid/distributor/local/LocalDistributor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,11 @@ public Either<SessionNotCreatedException, CreateSessionResponse> newSession(
586586
new SessionNotCreatedException("Unable to create new session");
587587
for (Capabilities caps : request.getDesiredCapabilities()) {
588588
if (isNotSupported(caps)) {
589+
// e.g. the last node drained, we have to wait for a new to register
590+
lastFailure =
591+
new SessionNotCreatedException(
592+
"Unable to find a node supporting the desired capabilities");
593+
retry = true;
589594
continue;
590595
}
591596

java/src/org/openqa/selenium/grid/node/httpd/NodeServer.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
package org.openqa.selenium.grid.node.httpd;
1919

20-
import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
20+
import static java.net.HttpURLConnection.HTTP_OK;
2121
import static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
2222
import static org.openqa.selenium.grid.config.StandardGridRoles.EVENT_BUS_ROLE;
2323
import static org.openqa.selenium.grid.config.StandardGridRoles.HTTPD_ROLE;
@@ -131,13 +131,16 @@ protected Handlers createHandlers(Config config) {
131131
HttpHandler readinessCheck =
132132
req -> {
133133
if (node.getStatus().hasCapacity()) {
134-
return new HttpResponse().setStatus(HTTP_NO_CONTENT);
134+
return new HttpResponse()
135+
.setStatus(HTTP_OK)
136+
.setHeader("Content-Type", MediaType.PLAIN_TEXT_UTF_8.toString())
137+
.setContent(Contents.utf8String("Node has capacity available"));
135138
}
136139

137140
return new HttpResponse()
138141
.setStatus(HTTP_UNAVAILABLE)
139142
.setHeader("Content-Type", MediaType.PLAIN_TEXT_UTF_8.toString())
140-
.setContent(Contents.utf8String("No capacity available"));
143+
.setContent(Contents.utf8String("Node has no capacity available"));
141144
};
142145

143146
bus.addListener(

java/src/org/openqa/selenium/grid/node/local/LocalNode.java

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,11 @@
5959
import java.util.concurrent.Executors;
6060
import java.util.concurrent.ScheduledExecutorService;
6161
import java.util.concurrent.TimeUnit;
62-
import java.util.concurrent.atomic.AtomicBoolean;
6362
import java.util.concurrent.atomic.AtomicInteger;
6463
import java.util.concurrent.atomic.AtomicLong;
64+
import java.util.concurrent.locks.Lock;
65+
import java.util.concurrent.locks.ReadWriteLock;
66+
import java.util.concurrent.locks.ReentrantReadWriteLock;
6567
import java.util.logging.Level;
6668
import java.util.logging.Logger;
6769
import java.util.stream.Collectors;
@@ -133,7 +135,7 @@ public class LocalNode extends Node implements Closeable {
133135
private final int connectionLimitPerSession;
134136

135137
private final boolean bidiEnabled;
136-
private final AtomicBoolean drainAfterSessions = new AtomicBoolean();
138+
private final boolean drainAfterSessions;
137139
private final List<SessionSlot> factories;
138140
private final Cache<SessionId, SessionSlot> currentSessions;
139141
private final Cache<SessionId, TemporaryFilesystem> uploadsTempFileSystem;
@@ -142,6 +144,7 @@ public class LocalNode extends Node implements Closeable {
142144
private final AtomicInteger pendingSessions = new AtomicInteger();
143145
private final AtomicInteger sessionCount = new AtomicInteger();
144146
private final Runnable shutdown;
147+
private final ReadWriteLock drainLock = new ReentrantReadWriteLock();
145148

146149
protected LocalNode(
147150
Tracer tracer,
@@ -177,7 +180,7 @@ protected LocalNode(
177180
this.factories = ImmutableList.copyOf(factories);
178181
Require.nonNull("Registration secret", registrationSecret);
179182
this.configuredSessionCount = drainAfterSessionCount;
180-
this.drainAfterSessions.set(this.configuredSessionCount > 0);
183+
this.drainAfterSessions = this.configuredSessionCount > 0;
181184
this.sessionCount.set(drainAfterSessionCount);
182185
this.cdpEnabled = cdpEnabled;
183186
this.bidiEnabled = bidiEnabled;
@@ -443,6 +446,9 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
443446
CreateSessionRequest sessionRequest) {
444447
Require.nonNull("Session request", sessionRequest);
445448

449+
Lock lock = drainLock.readLock();
450+
lock.lock();
451+
446452
try (Span span = tracer.getCurrentContext().createSpan("node.new_session")) {
447453
AttributeMap attributeMap = tracer.createAttributeMap();
448454
attributeMap.put(AttributeKey.LOGGER_CLASS.getKey(), getClass().getName());
@@ -455,13 +461,14 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
455461
span.setAttribute("current.session.count", currentSessionCount);
456462
attributeMap.put("current.session.count", currentSessionCount);
457463

458-
if (getCurrentSessionCount() >= maxSessionCount) {
464+
if (currentSessionCount >= maxSessionCount) {
459465
span.setAttribute(AttributeKey.ERROR.getKey(), true);
460466
span.setStatus(Status.RESOURCE_EXHAUSTED);
461467
attributeMap.put("max.session.count", maxSessionCount);
462468
span.addEvent("Max session count reached", attributeMap);
463469
return Either.left(new RetrySessionRequestException("Max session count reached."));
464470
}
471+
465472
if (isDraining()) {
466473
span.setStatus(
467474
Status.UNAVAILABLE.withDescription(
@@ -492,6 +499,15 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
492499
new RetrySessionRequestException("No slot matched the requested capabilities."));
493500
}
494501

502+
if (!decrementSessionCount()) {
503+
slotToUse.release();
504+
span.setAttribute(AttributeKey.ERROR.getKey(), true);
505+
span.setStatus(Status.RESOURCE_EXHAUSTED);
506+
attributeMap.put("drain.after.session.count", configuredSessionCount);
507+
span.addEvent("Drain after session count reached", attributeMap);
508+
return Either.left(new RetrySessionRequestException("Drain after session count reached."));
509+
}
510+
495511
UUID uuidForSessionDownloads = UUID.randomUUID();
496512
Capabilities desiredCapabilities = sessionRequest.getDesiredCapabilities();
497513
if (managedDownloadsRequested(desiredCapabilities)) {
@@ -548,6 +564,7 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
548564
return Either.left(possibleSession.left());
549565
}
550566
} finally {
567+
lock.unlock();
551568
checkSessionCount();
552569
}
553570
}
@@ -1020,20 +1037,40 @@ public void drain() {
10201037
}
10211038

10221039
private void checkSessionCount() {
1023-
if (this.drainAfterSessions.get()) {
1040+
if (this.drainAfterSessions) {
1041+
Lock lock = drainLock.writeLock();
1042+
if (!lock.tryLock()) {
1043+
// in case we can't get a write lock another thread does hold a read lock and will call
1044+
// checkSessionCount as soon as he releases the read lock. So we do not need to wait here
1045+
// for the other session to start and release the lock, just continue and let the other
1046+
// session start to drain the node.
1047+
return;
1048+
}
1049+
try {
1050+
int remainingSessions = this.sessionCount.get();
1051+
if (remainingSessions <= 0) {
1052+
LOG.info(
1053+
String.format(
1054+
"Draining Node, configured sessions value (%s) has been reached.",
1055+
this.configuredSessionCount));
1056+
drain();
1057+
}
1058+
} finally {
1059+
lock.unlock();
1060+
}
1061+
}
1062+
}
1063+
1064+
private boolean decrementSessionCount() {
1065+
if (this.drainAfterSessions) {
10241066
int remainingSessions = this.sessionCount.decrementAndGet();
10251067
LOG.log(
10261068
Debug.getDebugLogLevel(),
10271069
"{0} remaining sessions before draining Node",
10281070
remainingSessions);
1029-
if (remainingSessions <= 0) {
1030-
LOG.info(
1031-
String.format(
1032-
"Draining Node, configured sessions value (%s) has been reached.",
1033-
this.configuredSessionCount));
1034-
drain();
1035-
}
1071+
return remainingSessions >= 0;
10361072
}
1073+
return true;
10371074
}
10381075

10391076
private Map<String, Object> toJson() {

java/test/org/openqa/selenium/grid/distributor/BUILD.bazel

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,56 @@
11
load("@rules_jvm_external//:defs.bzl", "artifact")
2-
load("//java:defs.bzl", "JUNIT5_DEPS", "java_test_suite")
2+
load("//java:defs.bzl", "JUNIT5_DEPS", "java_selenium_test_suite", "java_test_suite")
33
load("//java:version.bzl", "TOOLS_JAVA_VERSION")
44

5+
LARGE_TESTS = [
6+
"DrainTest.java",
7+
]
8+
9+
java_selenium_test_suite(
10+
name = "large-tests",
11+
size = "large",
12+
srcs = LARGE_TESTS,
13+
browsers = [
14+
"chrome",
15+
"firefox",
16+
"edge",
17+
],
18+
javacopts = [
19+
"--release",
20+
TOOLS_JAVA_VERSION,
21+
],
22+
tags = [
23+
"selenium-remote",
24+
],
25+
deps = [
26+
"//java/src/org/openqa/selenium/chrome",
27+
"//java/src/org/openqa/selenium/firefox",
28+
"//java/src/org/openqa/selenium/grid",
29+
"//java/src/org/openqa/selenium/grid/config",
30+
"//java/src/org/openqa/selenium/grid/distributor",
31+
"//java/src/org/openqa/selenium/json",
32+
"//java/src/org/openqa/selenium/remote",
33+
"//java/src/org/openqa/selenium/support",
34+
"//java/test/org/openqa/selenium/environment",
35+
"//java/test/org/openqa/selenium/grid/testing",
36+
"//java/test/org/openqa/selenium/remote/tracing:tracing-support",
37+
"//java/test/org/openqa/selenium/testing:annotations",
38+
"//java/test/org/openqa/selenium/testing:test-base",
39+
artifact("org.junit.jupiter:junit-jupiter-api"),
40+
artifact("org.junit.jupiter:junit-jupiter-params"),
41+
artifact("org.assertj:assertj-core"),
42+
"//java/src/org/openqa/selenium:core",
43+
"//java/src/org/openqa/selenium/remote/http",
44+
] + JUNIT5_DEPS,
45+
)
46+
547
java_test_suite(
648
name = "medium-tests",
749
size = "medium",
8-
srcs = glob(["*.java"]),
50+
srcs = glob(
51+
["*.java"],
52+
exclude = LARGE_TESTS,
53+
),
954
javacopts = [
1055
"--release",
1156
TOOLS_JAVA_VERSION,

0 commit comments

Comments
 (0)