Skip to content

Commit c735bb3

Browse files
authored
core: retry part 6, client options - maxAttempts
1 parent e33d39c commit c735bb3

5 files changed

Lines changed: 83 additions & 0 deletions

File tree

core/src/main/java/io/grpc/ForwardingChannelBuilder.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,18 @@ public T keepAliveWithoutCalls(boolean enable) {
163163
return thisT();
164164
}
165165

166+
@Override
167+
public T maxRetryAttempts(int maxRetryAttempts) {
168+
delegate().maxRetryAttempts(maxRetryAttempts);
169+
return thisT();
170+
}
171+
172+
@Override
173+
public T maxHedgedAttempts(int maxHedgedAttempts) {
174+
delegate().maxHedgedAttempts(maxHedgedAttempts);
175+
return thisT();
176+
}
177+
166178
@Override
167179
public T retryBufferSize(long bytes) {
168180
delegate().retryBufferSize(bytes);

core/src/main/java/io/grpc/ManagedChannelBuilder.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,40 @@ public T keepAliveWithoutCalls(boolean enable) {
327327
throw new UnsupportedOperationException();
328328
}
329329

330+
/**
331+
* Sets max number of retry attempts. The total number of retry attempts for each RPC will not
332+
* exceed this number even if service config may allow a higher number. Setting this number to
333+
* zero is not effectively the same as {@code disableRetry()} because the former does not disable
334+
* <a
335+
* href="https://github.com/grpc/proposal/blob/master/A6-client-retries.md#transparent-retries">
336+
* transparent retry</a>.
337+
*
338+
* <p>This method may not work as expected for the current release because retry is not fully
339+
* implemented yet.
340+
*
341+
* @return this
342+
* @since 1.11.0
343+
*/
344+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982")
345+
public T maxRetryAttempts(int maxRetryAttempts) {
346+
throw new UnsupportedOperationException();
347+
}
348+
349+
/**
350+
* Sets max number of hedged attempts. The total number of hedged attempts for each RPC will not
351+
* exceed this number even if service config may allow a higher number.
352+
*
353+
* <p>This method may not work as expected for the current release because retry is not fully
354+
* implemented yet.
355+
*
356+
* @return this
357+
* @since 1.11.0
358+
*/
359+
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/3982")
360+
public T maxHedgedAttempts(int maxHedgedAttempts) {
361+
throw new UnsupportedOperationException();
362+
}
363+
330364
/**
331365
* Sets the retry buffer size in bytes. If the buffer limit is exceeded, no RPC
332366
* could retry at the moment, and in hedging case all hedges but one of the same RPC will cancel.

core/src/main/java/io/grpc/internal/AbstractManagedChannelImplBuilder.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ public static ManagedChannelBuilder<?> forTarget(String target) {
127127

128128
long idleTimeoutMillis = IDLE_MODE_DEFAULT_TIMEOUT_MILLIS;
129129

130+
int maxRetryAttempts = 5;
131+
int maxHedgedAttempts = 5;
130132
long retryBufferSize = DEFAULT_RETRY_BUFFER_SIZE_IN_BYTES;
131133
long perRpcBufferLimit = DEFAULT_PER_RPC_BUFFER_LIMIT_IN_BYTES;
132134
boolean retryDisabled = true; // TODO(zdapeng): default to false
@@ -291,6 +293,18 @@ public final T idleTimeout(long value, TimeUnit unit) {
291293
return thisT();
292294
}
293295

296+
@Override
297+
public final T maxRetryAttempts(int maxRetryAttempts) {
298+
this.maxRetryAttempts = maxRetryAttempts;
299+
return thisT();
300+
}
301+
302+
@Override
303+
public final T maxHedgedAttempts(int maxHedgedAttempts) {
304+
this.maxHedgedAttempts = maxHedgedAttempts;
305+
return thisT();
306+
}
307+
294308
@Override
295309
public final T retryBufferSize(long bytes) {
296310
checkArgument(bytes > 0L, "retry buffer size must be positive");

core/src/main/java/io/grpc/internal/ManagedChannelImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ public final class ManagedChannelImpl extends ManagedChannel implements Instrume
205205
// One instance per channel.
206206
private final ChannelBufferMeter channelBufferUsed = new ChannelBufferMeter();
207207

208+
private final int maxRetryAttempts;
209+
private final int maxHedgedAttempts;
208210
private final long perRpcBufferLimit;
209211
private final long channelBufferLimit;
210212

@@ -512,6 +514,8 @@ ClientStream newSubstream(ClientStreamTracer.Factory tracerFactory, Metadata new
512514
this.userAgent = builder.userAgent;
513515
this.proxyDetector = proxyDetector;
514516

517+
this.maxRetryAttempts = builder.maxRetryAttempts;
518+
this.maxHedgedAttempts = builder.maxHedgedAttempts;
515519
this.channelBufferLimit = builder.retryBufferSize;
516520
this.perRpcBufferLimit = builder.perRpcBufferLimit;
517521
this.retryEnabled = !builder.retryDisabled;
@@ -1090,6 +1094,7 @@ public void run() {
10901094
}
10911095
}
10921096

1097+
// TODO(zdapeng): take client provided maxAttempts into account.
10931098
// TODO(zdapeng): implement it once the Gson dependency issue is resolved.
10941099
// TODO(zdapeng): test retryEnabled = true/flase really works as expected.
10951100
private static RetryPolicies getRetryPolicies(Attributes config) {

core/src/test/java/io/grpc/internal/AbstractManagedChannelImplBuilderTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,24 @@ public void idleTimeout() {
330330
assertEquals(TimeUnit.SECONDS.toMillis(30), builder.getIdleTimeoutMillis());
331331
}
332332

333+
@Test
334+
public void maxRetryAttempts() {
335+
Builder builder = new Builder("target");
336+
assertEquals(5, builder.maxRetryAttempts);
337+
338+
builder.maxRetryAttempts(3);
339+
assertEquals(3, builder.maxRetryAttempts);
340+
}
341+
342+
@Test
343+
public void maxHedgedAttempts() {
344+
Builder builder = new Builder("target");
345+
assertEquals(5, builder.maxHedgedAttempts);
346+
347+
builder.maxHedgedAttempts(3);
348+
assertEquals(3, builder.maxHedgedAttempts);
349+
}
350+
333351
@Test
334352
public void retryBufferSize() {
335353
Builder builder = new Builder("target");

0 commit comments

Comments
 (0)