From 509ba6753f795c00086ab4a49dd022fe3a22aff0 Mon Sep 17 00:00:00 2001 From: cachescrubber Date: Thu, 31 Aug 2023 16:55:37 +0200 Subject: [PATCH] Document exec chain behaviour when automatic retries are enabled. (#480) --- .../http/async/AsyncExecChainHandler.java | 17 ++++++++++++++++- .../client5/http/classic/ExecChainHandler.java | 16 ++++++++++++++++ .../impl/async/AsyncHttpRequestRetryExec.java | 17 +++++++++++++++++ .../http/impl/classic/HttpRequestRetryExec.java | 17 +++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChainHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChainHandler.java index 3888617fc..5ba3d42cc 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChainHandler.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/async/AsyncExecChainHandler.java @@ -28,6 +28,9 @@ package org.apache.hc.client5.http.async; import java.io.IOException; +import org.apache.hc.client5.http.impl.ChainElement; +import org.apache.hc.client5.http.impl.async.AsyncHttpRequestRetryExec; +import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.http.HttpException; @@ -39,8 +42,20 @@ import org.apache.hc.core5.http.nio.AsyncEntityProducer; * chain. Handlers can either be a decorator around another element that implements * a cross cutting aspect or a self-contained executor capable of producing a response * for the given request. - * + *

+ * For information regarding the handler chain behaviour in case of a request re-execution, + * please refer to the {@link AsyncHttpRequestRetryExec} javadoc. + *

+ *

+ * Well known request execution handlers could be referred to by name using one of the + * {@link ChainElement} enum values. + *

* @since 5.0 + * @see ChainElement + * @see HttpAsyncClientBuilder#addExecInterceptorFirst(String, AsyncExecChainHandler) + * @see HttpAsyncClientBuilder#addExecInterceptorBefore(String, String, AsyncExecChainHandler) + * @see HttpAsyncClientBuilder#addExecInterceptorAfter(String, String, AsyncExecChainHandler) + * @see HttpAsyncClientBuilder#addExecInterceptorLast(String, AsyncExecChainHandler) */ @Contract(threading = ThreadingBehavior.STATELESS) public interface AsyncExecChainHandler { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecChainHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecChainHandler.java index 035c1000d..ae5de86bc 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecChainHandler.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/classic/ExecChainHandler.java @@ -29,6 +29,9 @@ package org.apache.hc.client5.http.classic; import java.io.IOException; +import org.apache.hc.client5.http.impl.ChainElement; +import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; +import org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.http.ClassicHttpRequest; @@ -46,8 +49,21 @@ import org.apache.hc.core5.http.HttpException; * by calling {@link ClassicHttpResponse#close()} methods in case of an I/O, protocol or * runtime exception, or in case the response is not propagated to the caller. *

+ *

+ * For information regarding the handler chain behaviour in case of a request re-execution, + * please refer to the {@link HttpRequestRetryExec} javadoc. + *

+ *

+ * Well known request execution handlers could be referred to by name using one of the + * {@link ChainElement} enum values. + *

* * @since 4.3 + * @see ChainElement + * @see HttpClientBuilder#addExecInterceptorFirst(String, ExecChainHandler) + * @see HttpClientBuilder#addExecInterceptorBefore(String, String, ExecChainHandler) + * @see HttpClientBuilder#addExecInterceptorAfter(String, String, ExecChainHandler) + * @see HttpClientBuilder#addExecInterceptorLast(String, ExecChainHandler) */ @Contract(threading = ThreadingBehavior.STATELESS) public interface ExecChainHandler { diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncHttpRequestRetryExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncHttpRequestRetryExec.java index 9fc7c3296..a1c338777 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncHttpRequestRetryExec.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncHttpRequestRetryExec.java @@ -33,6 +33,7 @@ import org.apache.hc.client5.http.HttpRoute; import org.apache.hc.client5.http.async.AsyncExecCallback; import org.apache.hc.client5.http.async.AsyncExecChain; import org.apache.hc.client5.http.async.AsyncExecChainHandler; +import org.apache.hc.client5.http.impl.ChainElement; import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Internal; @@ -61,6 +62,22 @@ import org.slf4j.LoggerFactory; * endpoint is delegated to the next executor in the request execution * chain. *

+ *

+ * If this handler is active, pay particular attention to the placement + * of other handlers within the handler chain relative to the retry handler. + * Use {@link ChainElement#RETRY} as name when referring to this handler. + *

+ *

+ * If a custom handler is placed before the retry handler, the handler will + * see the initial request and the final outcome after the last retry. Elapsed time + * will account for any delays imposed by the retry handler. + *

+ * + *

+ * A custom handler which is placed after the retry handler will be invoked for + * each individual retry. Elapsed time will measure each individual http request, + * without the delay imposed by the retry handler. + *

* * @since 5.0 */ diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpRequestRetryExec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpRequestRetryExec.java index 75e75d19f..fbd464c94 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpRequestRetryExec.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpRequestRetryExec.java @@ -35,6 +35,7 @@ import org.apache.hc.client5.http.classic.ExecChain; import org.apache.hc.client5.http.classic.ExecChain.Scope; import org.apache.hc.client5.http.classic.ExecChainHandler; import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.ChainElement; import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Internal; @@ -61,6 +62,22 @@ import org.slf4j.LoggerFactory; * endpoint is delegated to the next executor in the request execution * chain. *

+ *

+ * If this handler is active, pay particular attention to the placement + * of other handlers within the handler chain relative to the retry handler. + * Use {@link ChainElement#RETRY} as name when referring to this handler. + *

+ *

+ * If a custom handler is placed before the retry handler, the handler will + * see the initial request and the final outcome after the last retry. Elapsed time + * will account for any delays imposed by the retry handler. + *

+ * + *

+ * A custom handler which is placed after the retry handler will be invoked for + * each individual retry. Elapsed time will measure each individual http request, + * without the delay imposed by the retry handler. + *

* * @since 5.0 */