Skip to content

Commit

Permalink
Merge branch 'trunk' into renovate/rules_oci-1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
diemol authored Jan 2, 2025
2 parents 1b79d7b + 513c221 commit 8083228
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 28 deletions.
6 changes: 3 additions & 3 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ bazel_dep(name = "protobuf", version = "29.2", dev_dependency = True, repo_name
bazel_dep(name = "rules_cc", version = "0.0.9", dev_dependency = True)

bazel_dep(name = "rules_dotnet", version = "0.17.5")
bazel_dep(name = "rules_java", version = "7.11.1")
bazel_dep(name = "rules_java", version = "7.12.4")
bazel_dep(name = "rules_jvm_external", version = "6.6")
bazel_dep(name = "rules_nodejs", version = "6.3.2")
bazel_dep(name = "rules_oci", version = "1.8.0")
Expand Down Expand Up @@ -177,7 +177,7 @@ maven.install(
"com.google.auto:auto-common:1.2.2",
"com.google.auto.service:auto-service:1.1.1",
"com.google.auto.service:auto-service-annotations:1.1.1",
"com.google.googlejavaformat:google-java-format:jar:1.25.0",
"com.google.googlejavaformat:google-java-format:1.25.2:1.25.0",
"com.graphql-java:graphql-java:22.3",
"dev.failsafe:failsafe:3.3.2",
"io.grpc:grpc-context:1.68.1",
Expand Down Expand Up @@ -217,7 +217,7 @@ maven.install(
"org.junit.platform:junit-platform-commons",
"org.junit.platform:junit-platform-engine",
"org.mockito:mockito-core:5.14.2",
"org.redisson:redisson:3.39.0",
"org.redisson:redisson:3.41.0",
"org.slf4j:slf4j-api:2.0.16",
"org.slf4j:slf4j-jdk14:2.0.16",
"org.tomlj:tomlj:1.1.1",
Expand Down
10 changes: 5 additions & 5 deletions java/maven_install.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
"__INPUT_ARTIFACTS_HASH": 818842380,
"__RESOLVED_ARTIFACTS_HASH": 1188602649,
"__INPUT_ARTIFACTS_HASH": 267304004,
"__RESOLVED_ARTIFACTS_HASH": -1966274188,
"artifacts": {
"com.beust:jcommander": {
"shasums": {
Expand Down Expand Up @@ -739,10 +739,10 @@
},
"org.redisson:redisson": {
"shasums": {
"jar": "6e905eabe16b5b53ee021293ac1fc4b56db2296ecdb341f6e2e27e93e8fefd22",
"sources": "654232025331ac2191a5e522f82fdf56253976c17ea54a269cf0cbcdb738d2d9"
"jar": "c0198bb5963c65ad0216b0eaee2532d6a9730322ee35891ff45f1d8bcc921d14",
"sources": "67145b1a703580f00509eeea2d68bebbc27628be146f3bdd0dec2e14e5d7327f"
},
"version": "3.39.0"
"version": "3.41.0"
},
"org.slf4j:slf4j-api": {
"shasums": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,11 @@ public Either<SessionNotCreatedException, CreateSessionResponse> newSession(
new SessionNotCreatedException("Unable to create new session");
for (Capabilities caps : request.getDesiredCapabilities()) {
if (isNotSupported(caps)) {
// e.g. the last node drained, we have to wait for a new to register
lastFailure =
new SessionNotCreatedException(
"Unable to find a node supporting the desired capabilities");
retry = true;
continue;
}

Expand Down
9 changes: 6 additions & 3 deletions java/src/org/openqa/selenium/grid/node/httpd/NodeServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

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

import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
import static java.net.HttpURLConnection.HTTP_OK;
import static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
import static org.openqa.selenium.grid.config.StandardGridRoles.EVENT_BUS_ROLE;
import static org.openqa.selenium.grid.config.StandardGridRoles.HTTPD_ROLE;
Expand Down Expand Up @@ -131,13 +131,16 @@ protected Handlers createHandlers(Config config) {
HttpHandler readinessCheck =
req -> {
if (node.getStatus().hasCapacity()) {
return new HttpResponse().setStatus(HTTP_NO_CONTENT);
return new HttpResponse()
.setStatus(HTTP_OK)
.setHeader("Content-Type", MediaType.PLAIN_TEXT_UTF_8.toString())
.setContent(Contents.utf8String("Node has capacity available"));
}

return new HttpResponse()
.setStatus(HTTP_UNAVAILABLE)
.setHeader("Content-Type", MediaType.PLAIN_TEXT_UTF_8.toString())
.setContent(Contents.utf8String("No capacity available"));
.setContent(Contents.utf8String("Node has no capacity available"));
};

bus.addListener(
Expand Down
61 changes: 49 additions & 12 deletions java/src/org/openqa/selenium/grid/node/local/LocalNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -133,7 +135,7 @@ public class LocalNode extends Node implements Closeable {
private final int connectionLimitPerSession;

private final boolean bidiEnabled;
private final AtomicBoolean drainAfterSessions = new AtomicBoolean();
private final boolean drainAfterSessions;
private final List<SessionSlot> factories;
private final Cache<SessionId, SessionSlot> currentSessions;
private final Cache<SessionId, TemporaryFilesystem> uploadsTempFileSystem;
Expand All @@ -142,6 +144,7 @@ public class LocalNode extends Node implements Closeable {
private final AtomicInteger pendingSessions = new AtomicInteger();
private final AtomicInteger sessionCount = new AtomicInteger();
private final Runnable shutdown;
private final ReadWriteLock drainLock = new ReentrantReadWriteLock();

protected LocalNode(
Tracer tracer,
Expand Down Expand Up @@ -177,7 +180,7 @@ protected LocalNode(
this.factories = ImmutableList.copyOf(factories);
Require.nonNull("Registration secret", registrationSecret);
this.configuredSessionCount = drainAfterSessionCount;
this.drainAfterSessions.set(this.configuredSessionCount > 0);
this.drainAfterSessions = this.configuredSessionCount > 0;
this.sessionCount.set(drainAfterSessionCount);
this.cdpEnabled = cdpEnabled;
this.bidiEnabled = bidiEnabled;
Expand Down Expand Up @@ -443,6 +446,9 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
CreateSessionRequest sessionRequest) {
Require.nonNull("Session request", sessionRequest);

Lock lock = drainLock.readLock();
lock.lock();

try (Span span = tracer.getCurrentContext().createSpan("node.new_session")) {
AttributeMap attributeMap = tracer.createAttributeMap();
attributeMap.put(AttributeKey.LOGGER_CLASS.getKey(), getClass().getName());
Expand All @@ -455,13 +461,14 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
span.setAttribute("current.session.count", currentSessionCount);
attributeMap.put("current.session.count", currentSessionCount);

if (getCurrentSessionCount() >= maxSessionCount) {
if (currentSessionCount >= maxSessionCount) {
span.setAttribute(AttributeKey.ERROR.getKey(), true);
span.setStatus(Status.RESOURCE_EXHAUSTED);
attributeMap.put("max.session.count", maxSessionCount);
span.addEvent("Max session count reached", attributeMap);
return Either.left(new RetrySessionRequestException("Max session count reached."));
}

if (isDraining()) {
span.setStatus(
Status.UNAVAILABLE.withDescription(
Expand Down Expand Up @@ -492,6 +499,15 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
new RetrySessionRequestException("No slot matched the requested capabilities."));
}

if (!decrementSessionCount()) {
slotToUse.release();
span.setAttribute(AttributeKey.ERROR.getKey(), true);
span.setStatus(Status.RESOURCE_EXHAUSTED);
attributeMap.put("drain.after.session.count", configuredSessionCount);
span.addEvent("Drain after session count reached", attributeMap);
return Either.left(new RetrySessionRequestException("Drain after session count reached."));
}

UUID uuidForSessionDownloads = UUID.randomUUID();
Capabilities desiredCapabilities = sessionRequest.getDesiredCapabilities();
if (managedDownloadsRequested(desiredCapabilities)) {
Expand Down Expand Up @@ -548,6 +564,7 @@ public Either<WebDriverException, CreateSessionResponse> newSession(
return Either.left(possibleSession.left());
}
} finally {
lock.unlock();
checkSessionCount();
}
}
Expand Down Expand Up @@ -1020,20 +1037,40 @@ public void drain() {
}

private void checkSessionCount() {
if (this.drainAfterSessions.get()) {
if (this.drainAfterSessions) {
Lock lock = drainLock.writeLock();
if (!lock.tryLock()) {
// in case we can't get a write lock another thread does hold a read lock and will call
// checkSessionCount as soon as he releases the read lock. So we do not need to wait here
// for the other session to start and release the lock, just continue and let the other
// session start to drain the node.
return;
}
try {
int remainingSessions = this.sessionCount.get();
if (remainingSessions <= 0) {
LOG.info(
String.format(
"Draining Node, configured sessions value (%s) has been reached.",
this.configuredSessionCount));
drain();
}
} finally {
lock.unlock();
}
}
}

private boolean decrementSessionCount() {
if (this.drainAfterSessions) {
int remainingSessions = this.sessionCount.decrementAndGet();
LOG.log(
Debug.getDebugLogLevel(),
"{0} remaining sessions before draining Node",
remainingSessions);
if (remainingSessions <= 0) {
LOG.info(
String.format(
"Draining Node, configured sessions value (%s) has been reached.",
this.configuredSessionCount));
drain();
}
return remainingSessions >= 0;
}
return true;
}

private Map<String, Object> toJson() {
Expand Down
49 changes: 47 additions & 2 deletions java/test/org/openqa/selenium/grid/distributor/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,11 +1,56 @@
load("@rules_jvm_external//:defs.bzl", "artifact")
load("//java:defs.bzl", "JUNIT5_DEPS", "java_test_suite")
load("//java:defs.bzl", "JUNIT5_DEPS", "java_selenium_test_suite", "java_test_suite")
load("//java:version.bzl", "TOOLS_JAVA_VERSION")

LARGE_TESTS = [
"DrainTest.java",
]

java_selenium_test_suite(
name = "large-tests",
size = "large",
srcs = LARGE_TESTS,
browsers = [
"chrome",
"firefox",
"edge",
],
javacopts = [
"--release",
TOOLS_JAVA_VERSION,
],
tags = [
"selenium-remote",
],
deps = [
"//java/src/org/openqa/selenium/chrome",
"//java/src/org/openqa/selenium/firefox",
"//java/src/org/openqa/selenium/grid",
"//java/src/org/openqa/selenium/grid/config",
"//java/src/org/openqa/selenium/grid/distributor",
"//java/src/org/openqa/selenium/json",
"//java/src/org/openqa/selenium/remote",
"//java/src/org/openqa/selenium/support",
"//java/test/org/openqa/selenium/environment",
"//java/test/org/openqa/selenium/grid/testing",
"//java/test/org/openqa/selenium/remote/tracing:tracing-support",
"//java/test/org/openqa/selenium/testing:annotations",
"//java/test/org/openqa/selenium/testing:test-base",
artifact("org.junit.jupiter:junit-jupiter-api"),
artifact("org.junit.jupiter:junit-jupiter-params"),
artifact("org.assertj:assertj-core"),
"//java/src/org/openqa/selenium:core",
"//java/src/org/openqa/selenium/remote/http",
] + JUNIT5_DEPS,
)

java_test_suite(
name = "medium-tests",
size = "medium",
srcs = glob(["*.java"]),
srcs = glob(
["*.java"],
exclude = LARGE_TESTS,
),
javacopts = [
"--release",
TOOLS_JAVA_VERSION,
Expand Down
Loading

0 comments on commit 8083228

Please sign in to comment.