Skip to content

Commit bcd69cb

Browse files
authored
Merge branch 'trunk' into py-deprecate-ftp-proxy
2 parents 96109bc + e943cc1 commit bcd69cb

File tree

3 files changed

+431
-2
lines changed

3 files changed

+431
-2
lines changed

java/src/org/openqa/selenium/Proxy.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public String toString() {
6767
}
6868

6969
private static final String PROXY_TYPE = "proxyType";
70-
private static final String FTP_PROXY = "ftpProxy";
70+
@Deprecated private static final String FTP_PROXY = "ftpProxy";
7171
private static final String HTTP_PROXY = "httpProxy";
7272
private static final String NO_PROXY = "noProxy";
7373
private static final String SSL_PROXY = "sslProxy";
@@ -80,7 +80,7 @@ public String toString() {
8080

8181
private ProxyType proxyType = ProxyType.UNSPECIFIED;
8282
private boolean autodetect = false;
83-
private @Nullable String ftpProxy;
83+
@Deprecated private @Nullable String ftpProxy;
8484
private @Nullable String httpProxy;
8585
private @Nullable String noProxy;
8686
private @Nullable String sslProxy;
@@ -225,7 +225,9 @@ public Proxy setAutodetect(boolean autodetect) {
225225
* Gets the FTP proxy.
226226
*
227227
* @return the FTP proxy hostname if present, or null if not set
228+
* @deprecated getFtpProxy is deprecated and will be removed in a future release.
228229
*/
230+
@Deprecated
229231
public @Nullable String getFtpProxy() {
230232
return ftpProxy;
231233
}
@@ -235,7 +237,9 @@ public Proxy setAutodetect(boolean autodetect) {
235237
*
236238
* @param ftpProxy the proxy host, expected format is <code>hostname.com:1234</code>
237239
* @return reference to self
240+
* @deprecated setFtpProxy is deprecated and will be removed in a future release.
238241
*/
242+
@Deprecated
239243
public Proxy setFtpProxy(String ftpProxy) {
240244
verifyProxyTypeCompatibility(ProxyType.MANUAL);
241245
this.proxyType = ProxyType.MANUAL;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
18+
package org.openqa.selenium.grid.distributor.selector;
19+
20+
import static com.google.common.collect.ImmutableSet.toImmutableSet;
21+
import static org.openqa.selenium.grid.data.Availability.UP;
22+
23+
import java.util.Comparator;
24+
import java.util.Set;
25+
import org.openqa.selenium.Capabilities;
26+
import org.openqa.selenium.grid.config.Config;
27+
import org.openqa.selenium.grid.data.NodeStatus;
28+
import org.openqa.selenium.grid.data.SemanticVersionComparator;
29+
import org.openqa.selenium.grid.data.Slot;
30+
import org.openqa.selenium.grid.data.SlotId;
31+
import org.openqa.selenium.grid.data.SlotMatcher;
32+
33+
/**
34+
* A greedy slot selector that aims to maximize node utilization by minimizing the number of
35+
* partially filled nodes. The algorithm works as follows: 1. Sort nodes by their utilization load
36+
* (descending). 2. Among nodes with the same utilization, prefer those with fewer total slots. 3.
37+
* Then sort by the last session created (oldest first). This approach helps to: - Fill up nodes
38+
* that are already partially utilized - Minimize the number of nodes that are partially filled -
39+
* Distribute load evenly across nodes
40+
*/
41+
public class GreedySlotSelector implements SlotSelector {
42+
43+
public static SlotSelector create(Config config) {
44+
return new GreedySlotSelector();
45+
}
46+
47+
@Override
48+
public Set<SlotId> selectSlot(
49+
Capabilities capabilities, Set<NodeStatus> nodes, SlotMatcher slotMatcher) {
50+
return nodes.stream()
51+
.filter(node -> node.hasCapacity(capabilities, slotMatcher) && node.getAvailability() == UP)
52+
.sorted(
53+
// First and foremost, sort by utilization ratio (descending)
54+
// This ensures we ALWAYS try to fill nodes that are already partially utilized first
55+
Comparator.comparingDouble(NodeStatus::getLoad)
56+
.reversed()
57+
// Then sort by total number of slots (ascending)
58+
// Among nodes with same utilization, prefer those with fewer total slots
59+
.thenComparingLong(node -> node.getSlots().size())
60+
// Then last session created (oldest first)
61+
.thenComparingLong(NodeStatus::getLastSessionCreated)
62+
// Then sort by stereotype browserVersion (descending order)
63+
.thenComparing(
64+
Comparator.comparing(
65+
NodeStatus::getBrowserVersion, new SemanticVersionComparator().reversed())))
66+
.flatMap(
67+
node ->
68+
node.getSlots().stream()
69+
.filter(slot -> slot.getSession() == null)
70+
.filter(slot -> slot.isSupporting(capabilities, slotMatcher))
71+
.map(Slot::getId))
72+
.collect(toImmutableSet());
73+
}
74+
}

0 commit comments

Comments
 (0)