Skip to content
Permalink
Browse files
feat: add setLogicalTimeout helper to RetrySettings (#1334)
* feat: add setLogicalTimeout helper to RetrySettings

* move tests for RetrySettings to its own class
  • Loading branch information
noahdietz committed Mar 25, 2021
1 parent 49efdc3 commit 97d32144e9de38a9e351dc34270aa41aef351151
@@ -256,39 +256,6 @@ public BatchingCallSettings.Builder<Integer, Integer> fakeMethodBatching() {
}
}

// RetrySettings
// ====

@Test
public void retrySettingsMerge() {
RetrySettings.Builder builder =
RetrySettings.newBuilder()
.setTotalTimeout(Duration.ofMillis(45000))
.setInitialRpcTimeout(Duration.ofMillis(2000))
.setRpcTimeoutMultiplier(1.5)
.setMaxRpcTimeout(Duration.ofMillis(30000))
.setInitialRetryDelay(Duration.ofMillis(100))
.setRetryDelayMultiplier(1.2)
.setMaxRetryDelay(Duration.ofMillis(1000));
RetrySettings.Builder mergedBuilder = RetrySettings.newBuilder();
mergedBuilder.merge(builder);

RetrySettings settingsA = builder.build();
RetrySettings settingsB = mergedBuilder.build();

Truth.assertThat(settingsA.getTotalTimeout()).isEqualTo(settingsB.getTotalTimeout());
Truth.assertThat(settingsA.getInitialRetryDelay()).isEqualTo(settingsB.getInitialRetryDelay());
Truth.assertThat(settingsA.getRpcTimeoutMultiplier())
.isWithin(0)
.of(settingsB.getRpcTimeoutMultiplier());
Truth.assertThat(settingsA.getMaxRpcTimeout()).isEqualTo(settingsB.getMaxRpcTimeout());
Truth.assertThat(settingsA.getInitialRetryDelay()).isEqualTo(settingsB.getInitialRetryDelay());
Truth.assertThat(settingsA.getRetryDelayMultiplier())
.isWithin(0)
.of(settingsB.getRetryDelayMultiplier());
Truth.assertThat(settingsA.getMaxRetryDelay()).isEqualTo(settingsB.getMaxRetryDelay());
}

// GrpcTransportProvider
// ====

@@ -296,6 +296,22 @@ public abstract static class Builder {
*/
public abstract Duration getMaxRpcTimeout();

/**
* Configures the timeout settings with the given timeout such that the logical call will take
* no longer than the given timeout and each RPC attempt will use only the time remaining in the
* logical call as a timeout.
*
* <p>Using this method in conjunction with individual {@link RetrySettings} timeout field
* setters is not advised, because only the order in which they are invoked determines which
* setter is respected.
*/
public Builder setLogicalTimeout(Duration timeout) {
return setRpcTimeoutMultiplier(1)
.setInitialRpcTimeout(timeout)
.setMaxRpcTimeout(timeout)
.setTotalTimeout(timeout);
}

abstract RetrySettings autoBuild();

public RetrySettings build() {
@@ -191,6 +191,22 @@ public interface ApiCallContext extends RetryingContext {
* StatusCode.Code.UNAVAILABLE,
* StatusCode.Code.DEADLINE_EXCEEDED));
* }</pre>
*
* Setting a logical call timeout for the context can be done similarly with {@link
* RetrySettings.Builder#setLogicalTimeout(Duration timeout)}.
*
* <p>Example usage:
*
* <pre>{@code
* ApiCallContext context = GrpcCallContext.createDefault()
* .withRetrySettings(RetrySettings.newBuilder()
* .setInitialRetryDelay(Duration.ofMillis(10L))
* .setMaxRetryDelay(Duration.ofSeconds(10L))
* .setRetryDelayMultiplier(1.4)
* .setMaxAttempts(10)
* .setLogicalTimeout(Duration.ofSeconds(30L))
* .build());
* }</pre>
*/
@BetaApi
ApiCallContext withRetrySettings(RetrySettings retrySettings);
@@ -0,0 +1,78 @@
/*
* Copyright 2021 Google LLC
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google LLC nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.google.api.gax.retrying;

import com.google.common.truth.Truth;
import org.junit.Test;
import org.threeten.bp.Duration;

public class RetrySettingsTest {

@Test
public void retrySettingsSetLogicalTimeout() {
Duration timeout = Duration.ofMillis(60000);
RetrySettings retrySettings = RetrySettings.newBuilder().setLogicalTimeout(timeout).build();

Truth.assertThat(retrySettings.getRpcTimeoutMultiplier()).isEqualTo(1);
Truth.assertThat(retrySettings.getInitialRpcTimeout()).isEqualTo(timeout);
Truth.assertThat(retrySettings.getMaxRpcTimeout()).isEqualTo(timeout);
Truth.assertThat(retrySettings.getTotalTimeout()).isEqualTo(timeout);
}

@Test
public void retrySettingsMerge() {
RetrySettings.Builder builder =
RetrySettings.newBuilder()
.setTotalTimeout(Duration.ofMillis(45000))
.setInitialRpcTimeout(Duration.ofMillis(2000))
.setRpcTimeoutMultiplier(1.5)
.setMaxRpcTimeout(Duration.ofMillis(30000))
.setInitialRetryDelay(Duration.ofMillis(100))
.setRetryDelayMultiplier(1.2)
.setMaxRetryDelay(Duration.ofMillis(1000));
RetrySettings.Builder mergedBuilder = RetrySettings.newBuilder();
mergedBuilder.merge(builder);

RetrySettings settingsA = builder.build();
RetrySettings settingsB = mergedBuilder.build();

Truth.assertThat(settingsA.getTotalTimeout()).isEqualTo(settingsB.getTotalTimeout());
Truth.assertThat(settingsA.getInitialRetryDelay()).isEqualTo(settingsB.getInitialRetryDelay());
Truth.assertThat(settingsA.getRpcTimeoutMultiplier())
.isWithin(0)
.of(settingsB.getRpcTimeoutMultiplier());
Truth.assertThat(settingsA.getMaxRpcTimeout()).isEqualTo(settingsB.getMaxRpcTimeout());
Truth.assertThat(settingsA.getInitialRetryDelay()).isEqualTo(settingsB.getInitialRetryDelay());
Truth.assertThat(settingsA.getRetryDelayMultiplier())
.isWithin(0)
.of(settingsB.getRetryDelayMultiplier());
Truth.assertThat(settingsA.getMaxRetryDelay()).isEqualTo(settingsB.getMaxRetryDelay());
}
}

0 comments on commit 97d3214

Please sign in to comment.