Skip to content

Commit bc0c8d2

Browse files
Adds parsing of slow start config
Signed-off-by: anurag.ag <[email protected]>
1 parent 3a19aa5 commit bc0c8d2

File tree

4 files changed

+144
-4
lines changed

4 files changed

+144
-4
lines changed

xds/src/main/java/io/grpc/xds/LoadBalancerConfigFactory.java

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.envoyproxy.envoy.config.cluster.v3.LoadBalancingPolicy;
3131
import io.envoyproxy.envoy.config.cluster.v3.LoadBalancingPolicy.Policy;
3232
import io.envoyproxy.envoy.extensions.load_balancing_policies.client_side_weighted_round_robin.v3.ClientSideWeightedRoundRobin;
33+
import io.envoyproxy.envoy.extensions.load_balancing_policies.common.v3.SlowStartConfig;
3334
import io.envoyproxy.envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest;
3435
import io.envoyproxy.envoy.extensions.load_balancing_policies.pick_first.v3.PickFirst;
3536
import io.envoyproxy.envoy.extensions.load_balancing_policies.ring_hash.v3.RingHash;
@@ -92,6 +93,14 @@ class LoadBalancerConfigFactory {
9293

9394
static final String ERROR_UTILIZATION_PENALTY = "errorUtilizationPenalty";
9495

96+
static final String AGGRESSION = "aggression";
97+
98+
static final String SLOW_START_WINDOW = "slowStartWindow";
99+
100+
static final String MIN_WEIGHT_PERCENT = "minWeightPercent";
101+
102+
static final String SLOW_START_CONFIG = "slowStartConfig";
103+
95104
/**
96105
* Factory method for creating a new {link LoadBalancerConfigConverter} for a given xDS {@link
97106
* Cluster}.
@@ -138,7 +147,8 @@ class LoadBalancerConfigFactory {
138147
String oobReportingPeriod,
139148
Boolean enableOobLoadReport,
140149
String weightUpdatePeriod,
141-
Float errorUtilizationPenalty) {
150+
Float errorUtilizationPenalty,
151+
ImmutableMap<String, ?> slowStartConfig) {
142152
ImmutableMap.Builder<String, Object> configBuilder = ImmutableMap.builder();
143153
if (blackoutPeriod != null) {
144154
configBuilder.put(BLACK_OUT_PERIOD, blackoutPeriod);
@@ -158,10 +168,29 @@ class LoadBalancerConfigFactory {
158168
if (errorUtilizationPenalty != null) {
159169
configBuilder.put(ERROR_UTILIZATION_PENALTY, errorUtilizationPenalty);
160170
}
171+
if (slowStartConfig != null) {
172+
configBuilder.put(SLOW_START_CONFIG, slowStartConfig);
173+
}
161174
return ImmutableMap.of(WeightedRoundRobinLoadBalancerProvider.SCHEME,
162175
configBuilder.buildOrThrow());
163176
}
164177

178+
private static ImmutableMap<String, ?> buildSlowStartConfig(Double minWeightPercent,
179+
Double aggression,
180+
String slowStartWindow) {
181+
ImmutableMap.Builder<String, Object> configBuilder = ImmutableMap.builder();
182+
if (minWeightPercent != null) {
183+
configBuilder.put(MIN_WEIGHT_PERCENT, minWeightPercent);
184+
}
185+
if (aggression != null) {
186+
configBuilder.put(AGGRESSION, aggression);
187+
}
188+
if (slowStartWindow != null) {
189+
configBuilder.put(SLOW_START_WINDOW, slowStartWindow);
190+
}
191+
return configBuilder.buildOrThrow();
192+
}
193+
165194
/**
166195
* Builds a service config JSON object for the least_request load balancer config based on the
167196
* given config values.
@@ -293,13 +322,28 @@ static class LoadBalancingPolicyConverter {
293322
wrr.hasOobReportingPeriod() ? Durations.toString(wrr.getOobReportingPeriod()) : null,
294323
wrr.hasEnableOobLoadReport() ? wrr.getEnableOobLoadReport().getValue() : null,
295324
wrr.hasWeightUpdatePeriod() ? Durations.toString(wrr.getWeightUpdatePeriod()) : null,
296-
wrr.hasErrorUtilizationPenalty() ? wrr.getErrorUtilizationPenalty().getValue() : null);
325+
wrr.hasErrorUtilizationPenalty() ? wrr.getErrorUtilizationPenalty().getValue() : null,
326+
wrr.hasSlowStartConfig() ? convertSlotStartConfig(wrr.getSlowStartConfig()) : null);
297327
} catch (IllegalArgumentException ex) {
298328
throw new ResourceInvalidException("Invalid duration in weighted round robin config: "
299329
+ ex.getMessage());
300330
}
301331
}
302332

333+
private static ImmutableMap<String, ?> convertSlotStartConfig(
334+
SlowStartConfig config) throws ResourceInvalidException {
335+
try {
336+
return buildSlowStartConfig(
337+
config.hasMinWeightPercent() ? config.getMinWeightPercent().getValue() : null,
338+
config.hasAggression() ? config.getAggression().getDefaultValue() : null,
339+
config.hasSlowStartWindow() ? Durations.toString(config.getSlowStartWindow()) : null
340+
);
341+
} catch (IllegalArgumentException ex) {
342+
throw new ResourceInvalidException("Invalid duration in slow start slowStart: "
343+
+ ex.getMessage());
344+
}
345+
}
346+
303347
/**
304348
* Converts a wrr_locality {@link Any} configuration to service config format.
305349
*/
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2025 The gRPC Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.grpc.xds;
18+
19+
final class SlowStartConfig {
20+
final double minWeightPercent;
21+
final double aggression;
22+
final long slowStartWindowNanos;
23+
24+
public static Builder newBuilder() {
25+
return new Builder();
26+
}
27+
28+
private SlowStartConfig(double minWeightPercent, double aggression, long slowStartWindowNanos) {
29+
this.minWeightPercent = minWeightPercent;
30+
this.aggression = aggression;
31+
this.slowStartWindowNanos = slowStartWindowNanos;
32+
}
33+
34+
static final class Builder {
35+
private double minWeightPercent = 10.0;
36+
private double aggression = 1.0;
37+
private long slowStartWindowNanos = 0L;
38+
39+
private Builder() {
40+
}
41+
42+
@SuppressWarnings("UnusedReturnValue")
43+
Builder setMinWeightPercent(double minWeightPercent) {
44+
this.minWeightPercent = minWeightPercent;
45+
return this;
46+
}
47+
48+
@SuppressWarnings("UnusedReturnValue")
49+
Builder setAggression(double aggression) {
50+
this.aggression = aggression;
51+
return this;
52+
}
53+
54+
@SuppressWarnings("UnusedReturnValue")
55+
Builder setSlowStartWindowNanos(long slowStartWindowNanos) {
56+
this.slowStartWindowNanos = slowStartWindowNanos;
57+
return this;
58+
}
59+
60+
SlowStartConfig build() {
61+
return new SlowStartConfig(minWeightPercent, aggression, slowStartWindowNanos);
62+
}
63+
}
64+
}

xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancer.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ static final class WeightedRoundRobinLoadBalancerConfig {
719719
final long oobReportingPeriodNanos;
720720
final long weightUpdatePeriodNanos;
721721
final float errorUtilizationPenalty;
722+
final SlowStartConfig slowStartConfig;
722723

723724
public static Builder newBuilder() {
724725
return new Builder();
@@ -729,13 +730,15 @@ private WeightedRoundRobinLoadBalancerConfig(long blackoutPeriodNanos,
729730
boolean enableOobLoadReport,
730731
long oobReportingPeriodNanos,
731732
long weightUpdatePeriodNanos,
732-
float errorUtilizationPenalty) {
733+
float errorUtilizationPenalty,
734+
SlowStartConfig slowStartConfig) {
733735
this.blackoutPeriodNanos = blackoutPeriodNanos;
734736
this.weightExpirationPeriodNanos = weightExpirationPeriodNanos;
735737
this.enableOobLoadReport = enableOobLoadReport;
736738
this.oobReportingPeriodNanos = oobReportingPeriodNanos;
737739
this.weightUpdatePeriodNanos = weightUpdatePeriodNanos;
738740
this.errorUtilizationPenalty = errorUtilizationPenalty;
741+
this.slowStartConfig = slowStartConfig;
739742
}
740743

741744
static final class Builder {
@@ -745,6 +748,7 @@ static final class Builder {
745748
long oobReportingPeriodNanos = 10_000_000_000L; // 10s
746749
long weightUpdatePeriodNanos = 1_000_000_000L; // 1s
747750
float errorUtilizationPenalty = 1.0F;
751+
SlowStartConfig slowStartConfig = SlowStartConfig.newBuilder().build();
748752

749753
private Builder() {
750754

@@ -782,10 +786,16 @@ Builder setErrorUtilizationPenalty(float errorUtilizationPenalty) {
782786
return this;
783787
}
784788

789+
@SuppressWarnings("UnusedReturnValue")
790+
Builder setSlowStartConfig(SlowStartConfig slowStartConfig) {
791+
this.slowStartConfig = slowStartConfig;
792+
return this;
793+
}
794+
785795
WeightedRoundRobinLoadBalancerConfig build() {
786796
return new WeightedRoundRobinLoadBalancerConfig(blackoutPeriodNanos,
787797
weightExpirationPeriodNanos, enableOobLoadReport, oobReportingPeriodNanos,
788-
weightUpdatePeriodNanos, errorUtilizationPenalty);
798+
weightUpdatePeriodNanos, errorUtilizationPenalty, slowStartConfig);
789799
}
790800
}
791801
}

xds/src/main/java/io/grpc/xds/WeightedRoundRobinLoadBalancerProvider.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ private ConfigOrError parseLoadBalancingPolicyConfigInternal(Map<String, ?> rawC
7878
Boolean enableOobLoadReport = JsonUtil.getBoolean(rawConfig, "enableOobLoadReport");
7979
Long weightUpdatePeriodNanos = JsonUtil.getStringAsDuration(rawConfig, "weightUpdatePeriod");
8080
Float errorUtilizationPenalty = JsonUtil.getNumberAsFloat(rawConfig, "errorUtilizationPenalty");
81+
Map<String, ?> slowStartConfig = JsonUtil.getObject(rawConfig, "slowStartConfig");
8182

8283
WeightedRoundRobinLoadBalancerConfig.Builder configBuilder =
8384
WeightedRoundRobinLoadBalancerConfig.newBuilder();
@@ -102,6 +103,27 @@ private ConfigOrError parseLoadBalancingPolicyConfigInternal(Map<String, ?> rawC
102103
if (errorUtilizationPenalty != null) {
103104
configBuilder.setErrorUtilizationPenalty(errorUtilizationPenalty);
104105
}
106+
if (slowStartConfig != null) {
107+
configBuilder.setSlowStartConfig(parseSlowStartConfig(slowStartConfig));
108+
}
105109
return ConfigOrError.fromConfig(configBuilder.build());
106110
}
111+
112+
private SlowStartConfig parseSlowStartConfig(Map<String, ?> rawConfig) {
113+
Double minWeightPercent = JsonUtil.getNumberAsDouble(rawConfig, "minWeightPercent");
114+
Double aggression = JsonUtil.getNumberAsDouble(rawConfig, "aggression");
115+
Long slowStartWindowNanos = JsonUtil.getStringAsDuration(rawConfig, "slowStartWindow");
116+
117+
SlowStartConfig.Builder configBuilder = SlowStartConfig.newBuilder();
118+
if (slowStartWindowNanos != null) {
119+
configBuilder.setSlowStartWindowNanos(slowStartWindowNanos);
120+
}
121+
if (aggression != null) {
122+
configBuilder.setAggression(aggression);
123+
}
124+
if (minWeightPercent != null) {
125+
configBuilder.setMinWeightPercent(minWeightPercent);
126+
}
127+
return configBuilder.build();
128+
}
107129
}

0 commit comments

Comments
 (0)