Skip to content

Commit 0cebca1

Browse files
authored
feat(java): retry strategy APIC-261 (#286)
1 parent 15feab4 commit 0cebca1

File tree

19 files changed

+493
-295
lines changed

19 files changed

+493
-295
lines changed

clients/algoliasearch-client-java-2/.openapi-generator-ignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ gradle*
1919

2020
# Selective source file
2121
algoliasearch-core/com/algolia/auth/**
22+
algoliasearch-core/com/algolia/ApiException.java
2223
algoliasearch-core/com/algolia/Configuration.java
2324
algoliasearch-core/com/algolia/Server*.java
2425
algoliasearch-core/com/algolia/StringUtil.java

clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/ApiException.java

Lines changed: 0 additions & 103 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.algolia.exceptions;
2+
3+
/** Exception thrown in case of API failure such as 4XX, 5XX error. */
4+
public class AlgoliaApiException extends AlgoliaRuntimeException {
5+
6+
public int getHttpErrorCode() {
7+
return httpErrorCode;
8+
}
9+
10+
private final int httpErrorCode;
11+
12+
public AlgoliaApiException(
13+
String message,
14+
Throwable cause,
15+
int httpErrorCode
16+
) {
17+
super(message, cause);
18+
this.httpErrorCode = httpErrorCode;
19+
}
20+
21+
public AlgoliaApiException(String message, int httpErrorCode) {
22+
super(message);
23+
this.httpErrorCode = httpErrorCode;
24+
}
25+
26+
public AlgoliaApiException(Throwable cause, int httpErrorCode) {
27+
super(cause);
28+
this.httpErrorCode = httpErrorCode;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.algolia.exceptions;
2+
3+
/**
4+
* Exception thrown when an error occurs during the retry strategy. For example: All hosts are
5+
* unreachable.
6+
*/
7+
public class AlgoliaRetryException extends AlgoliaRuntimeException {
8+
9+
public AlgoliaRetryException(String message, Throwable cause) {
10+
super(message, cause);
11+
}
12+
13+
public AlgoliaRetryException(String message) {
14+
super(message);
15+
}
16+
17+
public AlgoliaRetryException(Throwable cause) {
18+
super(cause);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.algolia.exceptions;
2+
3+
/** Exception thrown when an error occurs during the Serialization/Deserialization process */
4+
public class AlgoliaRuntimeException extends RuntimeException {
5+
6+
public AlgoliaRuntimeException(String message, Throwable cause) {
7+
super(message, cause);
8+
}
9+
10+
public AlgoliaRuntimeException(String message) {
11+
super(message);
12+
}
13+
14+
public AlgoliaRuntimeException(Throwable cause) {
15+
super(cause);
16+
}
17+
}

clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/HttpRequester.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.algolia.utils;
22

33
import com.algolia.ApiCallback;
4-
import com.algolia.ApiException;
54
import com.algolia.ProgressResponseBody;
5+
import com.algolia.utils.retry.RetryStrategy;
6+
import com.algolia.utils.retry.StatefulHost;
67
import java.io.IOException;
8+
import java.util.List;
79
import java.util.concurrent.TimeUnit;
810
import okhttp3.Call;
911
import okhttp3.Interceptor;
@@ -15,18 +17,23 @@
1517

1618
public class HttpRequester implements Requester {
1719

20+
private RetryStrategy retryStrategy;
1821
private OkHttpClient httpClient;
1922
private HttpLoggingInterceptor loggingInterceptor;
2023
private boolean debugging;
2124

22-
public HttpRequester() {
25+
public HttpRequester(List<StatefulHost> hosts) {
26+
this.retryStrategy = new RetryStrategy(hosts);
27+
2328
OkHttpClient.Builder builder = new OkHttpClient.Builder();
29+
builder.addInterceptor(retryStrategy.getRetryInterceptor());
2430
builder.addNetworkInterceptor(getProgressInterceptor());
31+
builder.retryOnConnectionFailure(false);
2532

2633
httpClient = builder.build();
2734
}
2835

29-
public Call newCall(Request request) throws ApiException {
36+
public Call newCall(Request request) {
3037
return httpClient.newCall(request);
3138
}
3239

clients/algoliasearch-client-java-2/algoliasearch-core/com/algolia/utils/Requester.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package com.algolia.utils;
22

3-
import com.algolia.ApiException;
43
import okhttp3.Call;
54
import okhttp3.Request;
65

76
public interface Requester {
8-
public Call newCall(Request request) throws ApiException;
7+
public Call newCall(Request request);
98

109
/**
1110
* Enable/disable debugging for this API client.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.algolia.utils;
2+
3+
import java.time.Clock;
4+
import java.time.Instant;
5+
import java.time.OffsetDateTime;
6+
import java.time.ZoneOffset;
7+
import java.time.zone.ZoneRules;
8+
9+
public class Utils {
10+
11+
private static final ZoneRules ZONE_RULES_UTC = ZoneOffset.UTC.getRules();
12+
13+
/**
14+
* Memory optimization for getZoneRules with the same ZoneOffset (UTC). ZoneRules is immutable and
15+
* threadsafe, but getRules method consumes a lot of memory during load testing.
16+
*/
17+
public static OffsetDateTime nowUTC() {
18+
final Instant now = Clock.system(ZoneOffset.UTC).instant();
19+
return OffsetDateTime.ofInstant(now, ZONE_RULES_UTC.getOffset(now));
20+
}
21+
}
Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,46 @@
11
package com.algolia.utils.echo;
22

3-
import com.algolia.ApiException;
43
import com.algolia.utils.Requester;
54
import okhttp3.Request;
65

76
public class EchoRequester implements Requester {
87

9-
public CallEcho newCall(Request request) throws ApiException {
8+
private int connectionTimeout, readTimeout, writeTimeout;
9+
10+
public EchoRequester() {
11+
this.connectionTimeout = 100;
12+
this.readTimeout = 100;
13+
this.writeTimeout = 100;
14+
}
15+
16+
public CallEcho newCall(Request request) {
1017
return new CallEcho(request);
1118
}
1219

1320
// NO-OP for now
14-
1521
public void setDebugging(boolean debugging) {}
1622

1723
public int getConnectTimeout() {
18-
return 100;
24+
return this.connectionTimeout;
1925
}
2026

21-
public void setConnectTimeout(int connectionTimeout) {}
27+
public void setConnectTimeout(int connectionTimeout) {
28+
this.connectionTimeout = connectionTimeout;
29+
}
2230

2331
public int getReadTimeout() {
24-
return 100;
32+
return this.readTimeout;
2533
}
2634

27-
public void setReadTimeout(int readTimeout) {}
35+
public void setReadTimeout(int readTimeout) {
36+
this.readTimeout = readTimeout;
37+
}
2838

2939
public int getWriteTimeout() {
30-
return 100;
40+
return this.writeTimeout;
3141
}
3242

33-
public void setWriteTimeout(int writeTimeout) {}
43+
public void setWriteTimeout(int writeTimeout) {
44+
this.writeTimeout = writeTimeout;
45+
}
3446
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.algolia.utils.retry;
2+
3+
public enum CallType {
4+
READ,
5+
WRITE,
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.algolia.utils.retry;
2+
3+
public enum RetryOutcome {
4+
SUCCESS,
5+
RETRY,
6+
FAILURE,
7+
}

0 commit comments

Comments
 (0)