-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider adding a retry handler #21
Comments
Thanks for raising this. Given this is Clojure, it is pretty easy to wrap your requests to allow arbitrary retry logic on status codes / backoffs etc. Maybe the first step would be to document an example of this, and if it proves sufficiently useful/flexible, add it in as an opt-in feature via |
Wrapping it in a generic way is a little tricky as ;; Apache's http client automatically retries on IOExceptions, if you
;; would like to handle these retries yourself, you can specify a
;; :retry-handler. Return true to retry, false to stop trying:
(client/post "http://example.org" {:multipart [["title" "Foo"]
["Content/type" "text/plain"]
["file" (clojure.java.io/file "/tmp/missing-file")]]
:retry-handler (fn [ex try-count http-context]
(println "Got:" ex)
(if (> try-count 4) false true))}) The We have lots of services and copying retry logic can be tedious. We have a library now wrapping hato (using a common httpclient, timeouts, redirect policies, etc) where we're adding this but would certainly be nicer to have first class support as anyone using an http client in production wants it be resilient to transient failures w/o writing a bunch of custom code in most cases (definitely a selling point of OkHttp and Apache HttpClient). For reference, OkHttp has some default retry logic, but can be customized via the interceptor pattern: client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
int tryCount = 0;
int maxLimit = 3;
while (!response.isSuccessful() && tryCount < maxLimit) {
tryCount++;
// retry the request
response = chain.proceed(request);
}
return response;
}
}); |
Makes sense. Nice explanation. Let me review the PR. |
Would be nice to have this feature, but maybe not an entirely related problem and could be solved with something like https://github.com/resilience4clj/resilience4clj-retry more generically? |
@AndreaCrotti , I think folks can build a custom solution with resilience4j easily enough but it's difficult to do in a generic way as |
It’s common to want to retry (typically idempotent requests like GET/HEAD/OPTIONS) on certain failures such as IOExceptions. The JDK HttpClient does have some retry logic for ConnectException baked in, but it isn’t configurable. We’ve ran into some issues with the JDK HttpClient in prod with some random IOExceptions and connection reset issues for long lived connections which a simple retry would’ve been sufficient to get past the transient issue. Apache HttpClient (and clj-http by extension) by default will retry certain requests up to 3 times which is great and allows supplying a custom retry handler for doing things like exponential backoffs, dealing with rate limiting, etc which would be awesome to have for a production-ready client. It’s unfortunate the JDK HttpClient doesn’t expose this logic by default.
Thoughts?
The text was updated successfully, but these errors were encountered: