Skip to content

Commit ad7aad8

Browse files
authored
Merge branch 'trunk' into retry-after-drain
2 parents 9be0897 + c826fec commit ad7aad8

File tree

5 files changed

+128
-28
lines changed

5 files changed

+128
-28
lines changed

.bazelversion

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.3.1
1+
7.4.1

MODULE.bazel

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ bazel_dep(name = "contrib_rules_jvm", version = "0.27.0")
1212
bazel_dep(name = "platforms", version = "0.0.10")
1313

1414
# Required for the closure rules
15-
bazel_dep(name = "protobuf", version = "29.1", dev_dependency = True, repo_name = "com_google_protobuf")
15+
bazel_dep(name = "protobuf", version = "29.2", dev_dependency = True, repo_name = "com_google_protobuf")
1616

1717
# Required for rules_rust to import the crates properly
1818
bazel_dep(name = "rules_cc", version = "0.0.9", dev_dependency = True)
1919

2020
bazel_dep(name = "rules_dotnet", version = "0.17.5")
21-
bazel_dep(name = "rules_java", version = "7.11.1")
21+
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")
2424
bazel_dep(name = "rules_oci", version = "1.7.6")
@@ -177,7 +177,7 @@ maven.install(
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",
180-
"com.google.googlejavaformat:google-java-format:jar:1.25.0",
180+
"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",
183183
"io.grpc:grpc-context:1.68.1",
@@ -217,7 +217,7 @@ maven.install(
217217
"org.junit.platform:junit-platform-commons",
218218
"org.junit.platform:junit-platform-engine",
219219
"org.mockito:mockito-core:5.14.2",
220-
"org.redisson:redisson:3.39.0",
220+
"org.redisson:redisson:3.41.0",
221221
"org.slf4j:slf4j-api:2.0.16",
222222
"org.slf4j:slf4j-jdk14:2.0.16",
223223
"org.tomlj:tomlj:1.1.1",

java/maven_install.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
3-
"__INPUT_ARTIFACTS_HASH": 818842380,
4-
"__RESOLVED_ARTIFACTS_HASH": 1188602649,
3+
"__INPUT_ARTIFACTS_HASH": 267304004,
4+
"__RESOLVED_ARTIFACTS_HASH": -1966274188,
55
"artifacts": {
66
"com.beust:jcommander": {
77
"shasums": {
@@ -739,10 +739,10 @@
739739
},
740740
"org.redisson:redisson": {
741741
"shasums": {
742-
"jar": "6e905eabe16b5b53ee021293ac1fc4b56db2296ecdb341f6e2e27e93e8fefd22",
743-
"sources": "654232025331ac2191a5e522f82fdf56253976c17ea54a269cf0cbcdb738d2d9"
742+
"jar": "c0198bb5963c65ad0216b0eaee2532d6a9730322ee35891ff45f1d8bcc921d14",
743+
"sources": "67145b1a703580f00509eeea2d68bebbc27628be146f3bdd0dec2e14e5d7327f"
744744
},
745-
"version": "3.39.0"
745+
"version": "3.41.0"
746746
},
747747
"org.slf4j:slf4j-api": {
748748
"shasums": {

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() {

rust/Cargo.Bazel.lock

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"checksum": "d9285b63a8ce42183b3092dd0140c47d4711a9fa8b5016eaeaa0be37ec80b44b",
2+
"checksum": "87f471e3241881a49b45fd55d0a4e812b38e0ee58bf72dfbc091df4f5fe87ef5",
33
"crates": {
44
"addr2line 0.21.0": {
55
"name": "addr2line",
@@ -2039,16 +2039,79 @@
20392039
"id": "jobserver 0.1.31",
20402040
"target": "jobserver"
20412041
},
2042-
{
2043-
"id": "libc 0.2.168",
2044-
"target": "libc"
2045-
},
20462042
{
20472043
"id": "shlex 1.3.0",
20482044
"target": "shlex"
20492045
}
20502046
],
2051-
"selects": {}
2047+
"selects": {
2048+
"aarch64-apple-darwin": [
2049+
{
2050+
"id": "libc 0.2.168",
2051+
"target": "libc"
2052+
}
2053+
],
2054+
"aarch64-unknown-linux-gnu": [
2055+
{
2056+
"id": "libc 0.2.168",
2057+
"target": "libc"
2058+
}
2059+
],
2060+
"aarch64-unknown-nixos-gnu": [
2061+
{
2062+
"id": "libc 0.2.168",
2063+
"target": "libc"
2064+
}
2065+
],
2066+
"arm-unknown-linux-gnueabi": [
2067+
{
2068+
"id": "libc 0.2.168",
2069+
"target": "libc"
2070+
}
2071+
],
2072+
"i686-unknown-linux-gnu": [
2073+
{
2074+
"id": "libc 0.2.168",
2075+
"target": "libc"
2076+
}
2077+
],
2078+
"powerpc-unknown-linux-gnu": [
2079+
{
2080+
"id": "libc 0.2.168",
2081+
"target": "libc"
2082+
}
2083+
],
2084+
"s390x-unknown-linux-gnu": [
2085+
{
2086+
"id": "libc 0.2.168",
2087+
"target": "libc"
2088+
}
2089+
],
2090+
"x86_64-apple-darwin": [
2091+
{
2092+
"id": "libc 0.2.168",
2093+
"target": "libc"
2094+
}
2095+
],
2096+
"x86_64-unknown-freebsd": [
2097+
{
2098+
"id": "libc 0.2.168",
2099+
"target": "libc"
2100+
}
2101+
],
2102+
"x86_64-unknown-linux-gnu": [
2103+
{
2104+
"id": "libc 0.2.168",
2105+
"target": "libc"
2106+
}
2107+
],
2108+
"x86_64-unknown-nixos-gnu": [
2109+
{
2110+
"id": "libc 0.2.168",
2111+
"target": "libc"
2112+
}
2113+
]
2114+
}
20522115
},
20532116
"edition": "2018",
20542117
"version": "1.1.30"

0 commit comments

Comments
 (0)