Skip to content

Commit efee4a3

Browse files
committed
Add grpc interceptor
1 parent cf17b88 commit efee4a3

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

src/main/java/io/qdrant/client/QdrantGrpcClient.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ private static ManagedChannel createChannel(
269269
}
270270

271271
channelBuilder.userAgent(userAgent);
272+
channelBuilder.intercept(new ResourceExhaustedInterceptor());
272273

273274
return channelBuilder.build();
274275
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package io.qdrant.client;
2+
3+
import io.grpc.*;
4+
5+
/** An Interceptor that handles Resource Exhausted errors */
6+
public class ResourceExhaustedInterceptor implements ClientInterceptor {
7+
/** Default constructor for {@link ResourceExhaustedInterceptor} */
8+
public ResourceExhaustedInterceptor() {}
9+
10+
@Override
11+
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
12+
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
13+
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
14+
next.newCall(method, callOptions)) {
15+
16+
@Override
17+
public void start(Listener<RespT> responseListener, Metadata headers) {
18+
super.start(
19+
new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(
20+
responseListener) {
21+
@Override
22+
public void onClose(Status status, Metadata trailers) {
23+
if (status.getCode() == Status.Code.RESOURCE_EXHAUSTED) {
24+
String retryAfter =
25+
trailers.get(
26+
Metadata.Key.of("Retry-After", Metadata.ASCII_STRING_MARSHALLER));
27+
if (retryAfter != null) {
28+
try {
29+
int retryAfterSeconds = Integer.parseInt(retryAfter);
30+
status =
31+
status.withCause(
32+
new ResourceExhaustedResponse(
33+
"Too many requests", retryAfterSeconds));
34+
} catch (NumberFormatException e) {
35+
throw new QdrantException(
36+
"Retry-After header value is not a valid integer: " + retryAfter);
37+
}
38+
} else {
39+
super.onClose(status, trailers);
40+
}
41+
}
42+
super.onClose(status, trailers);
43+
}
44+
},
45+
headers);
46+
}
47+
};
48+
}
49+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.qdrant.client;
2+
3+
/** An exception indicating that rate limit is reached */
4+
public class ResourceExhaustedResponse extends RuntimeException {
5+
/** The number of seconds to wait before retrying */
6+
private final int retryAfterSeconds;
7+
8+
/**
9+
* Instantiates a new instance of {@link ResourceExhaustedResponse}
10+
*
11+
* @param message The message to display
12+
* @param retryAfterSeconds The number of seconds to wait before retrying
13+
*/
14+
public ResourceExhaustedResponse(String message, int retryAfterSeconds) {
15+
super(message);
16+
this.retryAfterSeconds = retryAfterSeconds;
17+
}
18+
19+
/**
20+
* Gets the number of seconds to wait before retrying
21+
*
22+
* @return the number of seconds to wait before retrying
23+
*/
24+
public int getRetryAfterSeconds() {
25+
return retryAfterSeconds;
26+
}
27+
}

0 commit comments

Comments
 (0)