spring-retry

Can I use spring-retry on no response?


Reading the docs I didn't see any mention of retrying if a call is taking too long. Does the RetryPolicy allow you to cancel a call before any response is received and initiate a retry?


Solution

  • A crucial part of the retry pattern is an exception, otherwise it cannot be called "retry" if no exception.

    Your "too long request" easily fits into a request timeout concept which is usual fail in client with a RequestTimeoutException. So, your retry advice for the service call with a timeout should be configured to catch such an exception and retry on it.

    This is really not a retry pattern responsibility to cancel request since there are just might not be such a hook or the cancelation can be too involved.

    See for example, RestTemplate and its SimpleClientHttpRequestFactory:

    /**
     * Set the underlying URLConnection's read timeout (in milliseconds).
     * A timeout value of 0 specifies an infinite timeout.
     * <p>Default is the system's default timeout.
     * @see URLConnection#setReadTimeout(int)
     */
    public void setReadTimeout(int readTimeout) {
    

    And its delegate:

    /**
     * Sets the read timeout to a specified timeout, in
     * milliseconds. A non-zero value specifies the timeout when
     * reading from Input stream when a connection is established to a
     * resource. If the timeout expires before there is data available
     * for read, a java.net.SocketTimeoutException is raised. A
     * timeout of zero is interpreted as an infinite timeout.
     *
     * <p> Some non-standard implementation of this method ignores the
     * specified timeout. To see the read timeout set, please call
     * getReadTimeout().
     *
     * @param timeout an {@code int} that specifies the timeout
     * value to be used in milliseconds
     * @throws IllegalArgumentException if the timeout parameter is negative
     *
     * @see #getReadTimeout()
     * @see InputStream#read()
     * @since 1.5
     */
    public void setReadTimeout(int timeout) {
    

    The RestTemplate will wrap that SocketTimeoutException into a ResourceAccessException: Using sping's restTemplate with a timeout, how do I detect a timeout?