Skip to content

Commit 299a909

Browse files
ASP-2043: Type serviceConfig in GrpcChannelConfig using GrpcServiceConfig and GrpcRetryPolicy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> AI-Session-Id: 75f3864c-dc2c-4e44-b4f3-b23c980f2ea6 AI-Tool: claude-code AI-Model: unknown
1 parent 4fe9c35 commit 299a909

5 files changed

Lines changed: 77 additions & 5 deletions

File tree

grpc-client-utils/src/main/java/org/hypertrace/core/grpcutils/client/GrpcChannelConfig.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import io.grpc.ClientInterceptor;
44
import java.util.List;
5-
import java.util.Map;
65
import lombok.Builder;
76
import lombok.Singular;
87
import lombok.Value;
@@ -14,5 +13,5 @@ public class GrpcChannelConfig {
1413

1514
@Singular List<ClientInterceptor> clientInterceptors;
1615

17-
Map<String, Object> serviceConfig;
16+
GrpcServiceConfig serviceConfig;
1817
}

grpc-client-utils/src/main/java/org/hypertrace/core/grpcutils/client/GrpcChannelRegistry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ protected ManagedChannel configureAndBuildChannel(
9191
builder.maxInboundMessageSize(config.getMaxInboundMessageSize());
9292
}
9393
if (config.getServiceConfig() != null) {
94-
builder.defaultServiceConfig(config.getServiceConfig()).enableRetry();
94+
builder.defaultServiceConfig(config.getServiceConfig().toMap()).enableRetry();
9595
}
9696
this.registryConfig.getDefaultInterceptors().forEach(builder::intercept);
9797
return builder.intercept(config.getClientInterceptors()).build();
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package org.hypertrace.core.grpcutils.client;
2+
3+
import static java.util.stream.Collectors.toUnmodifiableList;
4+
5+
import io.grpc.Status;
6+
import java.time.Duration;
7+
import java.util.List;
8+
import java.util.Map;
9+
import lombok.Builder;
10+
import lombok.Singular;
11+
import lombok.Value;
12+
13+
@Value
14+
@Builder
15+
public class GrpcRetryPolicy {
16+
private static final String MAX_ATTEMPTS = "maxAttempts";
17+
private static final String INITIAL_BACKOFF = "initialBackoff";
18+
private static final String MAX_BACKOFF = "maxBackoff";
19+
private static final String BACKOFF_MULTIPLIER = "backoffMultiplier";
20+
private static final String RETRYABLE_STATUS_CODES = "retryableStatusCodes";
21+
22+
int maxAttempts;
23+
Duration initialBackoff;
24+
Duration maxBackoff;
25+
double backoffMultiplier;
26+
@Singular List<Status.Code> retryableStatusCodes;
27+
28+
Map<String, Object> toMap() {
29+
return Map.of(
30+
MAX_ATTEMPTS,
31+
(double) maxAttempts,
32+
INITIAL_BACKOFF,
33+
initialBackoff.toMillis() / 1000.0 + "s",
34+
MAX_BACKOFF,
35+
maxBackoff.toMillis() / 1000.0 + "s",
36+
BACKOFF_MULTIPLIER,
37+
backoffMultiplier,
38+
RETRYABLE_STATUS_CODES,
39+
retryableStatusCodes.stream().map(Enum::name).collect(toUnmodifiableList()));
40+
}
41+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.hypertrace.core.grpcutils.client;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import lombok.Builder;
6+
import lombok.Value;
7+
8+
@Value
9+
@Builder
10+
public class GrpcServiceConfig {
11+
private static final String METHOD_CONFIG = "methodConfig";
12+
private static final String NAME = "name";
13+
private static final String RETRY_POLICY = "retryPolicy";
14+
15+
GrpcRetryPolicy retryPolicy;
16+
17+
Map<String, Object> toMap() {
18+
return Map.of(
19+
METHOD_CONFIG, List.of(Map.of(NAME, List.of(Map.of()), RETRY_POLICY, retryPolicy.toMap())));
20+
}
21+
}

grpc-client-utils/src/test/java/org/hypertrace/core/grpcutils/client/GrpcChannelRegistryTest.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
import io.grpc.Deadline.Ticker;
2323
import io.grpc.ManagedChannel;
2424
import io.grpc.ManagedChannelBuilder;
25+
import io.grpc.Status;
26+
import java.time.Duration;
2527
import java.util.List;
26-
import java.util.Map;
2728
import java.util.concurrent.TimeUnit;
2829
import org.junit.jupiter.api.BeforeEach;
2930
import org.junit.jupiter.api.Test;
@@ -148,7 +149,17 @@ void copyConstructorReusesExistingChannels() {
148149

149150
@Test
150151
void createsDistinctChannelsForDifferentServiceConfigs() {
151-
Map<String, Object> serviceConfig = Map.of("methodConfig", List.of());
152+
GrpcServiceConfig serviceConfig =
153+
GrpcServiceConfig.builder()
154+
.retryPolicy(
155+
GrpcRetryPolicy.builder()
156+
.maxAttempts(3)
157+
.initialBackoff(Duration.ofMillis(100))
158+
.maxBackoff(Duration.ofSeconds(1))
159+
.backoffMultiplier(2.0)
160+
.retryableStatusCode(Status.Code.UNAVAILABLE)
161+
.build())
162+
.build();
152163
Channel channelWithServiceConfig =
153164
this.channelRegistry.forSecureAddress(
154165
"foo", 1000, GrpcChannelConfig.builder().serviceConfig(serviceConfig).build());

0 commit comments

Comments
 (0)