Skip to content

Commit 8872a55

Browse files
committed
Creating RetryExecutor to inject it as a dependency in other components
1 parent 775c341 commit 8872a55

2 files changed

Lines changed: 99 additions & 0 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2022 Google LLC
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+
* https://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+
package com.google.cloud.datastore;
17+
18+
import com.google.api.core.ApiClock;
19+
import com.google.api.gax.retrying.ResultRetryAlgorithm;
20+
import com.google.api.gax.retrying.RetrySettings;
21+
import com.google.cloud.RetryHelper;
22+
import java.util.concurrent.Callable;
23+
24+
public class RetryExecutor {
25+
26+
public <T> T execute(Callable<T> block, RetrySettings retrySettings,
27+
ResultRetryAlgorithm<?> resultRetryAlgorithm, ApiClock clock) {
28+
return RetryHelper.runWithRetries(block, retrySettings, resultRetryAlgorithm, clock);
29+
}
30+
31+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2022 Google LLC
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+
* https://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+
package com.google.cloud.datastore;
17+
18+
import static org.hamcrest.CoreMatchers.equalTo;
19+
import static org.hamcrest.MatcherAssert.assertThat;
20+
21+
import com.google.api.core.NanoClock;
22+
import com.google.api.gax.retrying.BasicResultRetryAlgorithm;
23+
import com.google.api.gax.retrying.RetrySettings;
24+
import java.util.concurrent.Callable;
25+
import org.junit.Test;
26+
27+
public class RetryExecutorTest {
28+
29+
private RetryExecutor retryExecutor = new RetryExecutor();
30+
31+
@Test
32+
public void shouldRetryWhenErrorOccurred() {
33+
RetrySettings retrySettings = RetrySettings.newBuilder()
34+
.setMaxAttempts(4)
35+
.build();
36+
CustomErrorCallable callable = new CustomErrorCallable(3);
37+
38+
retryExecutor.execute(callable, retrySettings, new BasicResultRetryAlgorithm<>(),
39+
NanoClock.getDefaultClock());
40+
41+
assertThat(callable.invokedTimes(), equalTo(4));
42+
}
43+
44+
private static class CustomErrorCallable implements Callable<String> {
45+
46+
private final int errorThreshold;
47+
private int numberOfInvocations;
48+
49+
public CustomErrorCallable(int errorThreshold) {
50+
this.errorThreshold = errorThreshold;
51+
this.numberOfInvocations = 0;
52+
}
53+
54+
@Override
55+
public String call() throws Exception {
56+
this.numberOfInvocations++;
57+
if (this.numberOfInvocations <= errorThreshold) {
58+
throw new RuntimeException("error");
59+
}
60+
return "success";
61+
}
62+
63+
public int invokedTimes() {
64+
return this.numberOfInvocations;
65+
}
66+
}
67+
}
68+

0 commit comments

Comments
 (0)