armeria icon indicating copy to clipboard operation
armeria copied to clipboard

Retrofit client can’t have responseTimeout set longer than 15 seconds

Open kasecato opened this issue 4 months ago • 2 comments

When I combine RetryingClient with a responseTimeout in ArmeriaRetrofit, any response timeout value over 15 seconds is ignored even if the retry rule isn't triggered

public class Main {
    public static void main(String[] args) {
        final var exampleClient = ArmeriaRetrofit
                .builder("http://localhost:18080")
                .decorator(LoggingClient.newDecorator())
                // Any timeout longer than 15 seconds is ignored
                .responseTimeout(Duration.ofSeconds(20L)) // <- ignored
                // And RetryingClient’s timeout setting takes effect instead
                .decorator(RetryingClient.newDecorator(
                        RetryConfig.builder(RetryRule.builder()
                                                     .onException(NotImplementedError.class)
                                                     .thenNoRetry())
                                   .build()))
                .addConverterFactory(JacksonConverterFactory.create(new ObjectMapper()))
                .build()
                .create(ExampleClient.class);

        try {
            System.out.printf(exampleClient.timeoutLongerThan15seconds().get());
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    public interface ExampleClient {
        @GET("/")
        CompletableFuture<String> timeoutLongerThan15seconds();
    }
}
[creqId=1610d1c0, preqId=d79df21f, chanId=3ba4813a, laddr=127.0.0.1:53821, raddr=localhost/127.0.0.1:18080][http://localhost:18080/#GET] 
Response: {startTime=2025-09-03T03:05:07.893Z(1756868707893717), length=0B, duration=0ns, 
totalDuration=15054ms(15054054333ns), cause=com.linecorp.armeria.client.ResponseTimeoutException, headers=[:status=0]}
  • As-Is: totalDuration=15054ms
  • To-Be : totalDuration=20000ms

If an user doesn’t explicitly call responseTimeoutForEachAttempt(), RetryConfig should respect whatever value is configured in responseTimeout, not to use Flags.defaultResponseTimeoutMillis() by default

kasecato avatar Sep 03 '25 03:09 kasecato

If an user doesn’t explicitly call responseTimeoutForEachAttempt(), RetryConfig should respect whatever value is configured in responseTimeout, not to use Flags.defaultResponseTimeoutMillis() by default

That is intentional but I agree with your point. If responseTimeoutForEachAttempt() is not set, using the client default makes more sense.

ikhoon avatar Sep 03 '25 06:09 ikhoon

; or using ClientRequestContext.responseTimeoutMillis().

ikhoon avatar Sep 03 '25 06:09 ikhoon