Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

feat: add setLogicalTimeout helper to RetrySettings #1334

Merged
merged 5 commits into from Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 0 additions & 33 deletions gax-grpc/src/test/java/com/google/api/gax/grpc/SettingsTest.java
Expand Up @@ -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
// ====

Expand Down
12 changes: 12 additions & 0 deletions gax/src/main/java/com/google/api/gax/retrying/RetrySettings.java
Expand Up @@ -296,6 +296,18 @@ 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.
*/
public Builder setLogicalTimeout(Duration timeout) {
return setRpcTimeoutMultiplier(1)
.setInitialRpcTimeout(timeout)
.setMaxRpcTimeout(timeout)
.setTotalTimeout(timeout);
}

abstract RetrySettings autoBuild();

public RetrySettings build() {
Expand Down
16 changes: 16 additions & 0 deletions gax/src/main/java/com/google/api/gax/rpc/ApiCallContext.java
Expand Up @@ -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);
Expand Down
@@ -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());
}
}