Skip to content

Commit 8a9944f

Browse files
committed
#26 - Expose HttpClientRequest.responseTimeMicros() ... for ease of metrics interceptors
1 parent f03ee6b commit 8a9944f

File tree

8 files changed

+47
-19
lines changed

8 files changed

+47
-19
lines changed

http-client/client/src/main/java/io/avaje/http/client/BasicAuthIntercept.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,4 @@ public void beforeRequest(HttpClientRequest request) {
3131
request.header("Authorization", headerValue);
3232
}
3333

34-
@Override
35-
public void afterResponse(HttpResponse<?> response, HttpClientRequest request) {
36-
// do nothing
37-
}
3834
}

http-client/client/src/main/java/io/avaje/http/client/DHttpClientRequest.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse {
4343
private Map<String, List<String>> headers;
4444

4545
private boolean bodyFormEncoded;
46-
private long requestTimeNanos;
46+
private long responseTimeNanos;
4747

4848
private HttpResponse<?> httpResponse;
4949
private BodyContent encodedResponseBody;
@@ -421,7 +421,7 @@ protected <T> HttpResponse<T> performSend(HttpResponse.BodyHandler<T> responseHa
421421
try {
422422
return context.send(httpRequest, responseHandler);
423423
} finally {
424-
requestTimeNanos = System.nanoTime() - startNanos;
424+
responseTimeNanos = System.nanoTime() - startNanos;
425425
}
426426
}
427427

@@ -449,7 +449,7 @@ protected <E> List<E> asyncList(Class<E> type, HttpResponse<byte[]> response) {
449449
}
450450

451451
protected <E> Stream<E> asyncStream(Class<E> type, HttpResponse<Stream<String>> response) {
452-
requestTimeNanos = System.nanoTime() - startAsyncNanos;
452+
responseTimeNanos = System.nanoTime() - startAsyncNanos;
453453
httpResponse = response;
454454
context.afterResponse(this);
455455
if (response.statusCode() >= 300) {
@@ -460,20 +460,25 @@ protected <E> Stream<E> asyncStream(Class<E> type, HttpResponse<Stream<String>>
460460
}
461461

462462
private void afterAsyncEncoded(HttpResponse<byte[]> response) {
463-
requestTimeNanos = System.nanoTime() - startAsyncNanos;
463+
responseTimeNanos = System.nanoTime() - startAsyncNanos;
464464
httpResponse = response;
465465
encodedResponseBody = context.readContent(response);
466466
context.afterResponse(this);
467467
context.checkMaybeThrow(response);
468468
}
469469

470470
protected <E> HttpResponse<E> afterAsync(HttpResponse<E> response) {
471-
requestTimeNanos = System.nanoTime() - startAsyncNanos;
471+
responseTimeNanos = System.nanoTime() - startAsyncNanos;
472472
httpResponse = response;
473473
context.afterResponse(this);
474474
return response;
475475
}
476476

477+
@Override
478+
public long responseTimeMicros() {
479+
return responseTimeNanos / 1000;
480+
}
481+
477482
@Override
478483
public HttpResponse<byte[]> asByteArray() {
479484
return withHandler(HttpResponse.BodyHandlers.ofByteArray());
@@ -573,8 +578,8 @@ boolean isSkipAuthToken() {
573578
private class ListenerEvent implements RequestListener.Event {
574579

575580
@Override
576-
public long responseTimeNanos() {
577-
return requestTimeNanos;
581+
public long responseTimeMicros() {
582+
return responseTimeNanos / 1000;
578583
}
579584

580585
@Override

http-client/client/src/main/java/io/avaje/http/client/HttpClientRequest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.InputStream;
44
import java.net.http.HttpRequest;
5+
import java.net.http.HttpResponse;
56
import java.nio.file.Path;
67
import java.time.Duration;
78
import java.util.List;
@@ -345,4 +346,10 @@ default HttpClientResponse delete() {
345346
*/
346347
HttpClientResponse HEAD();
347348

349+
/**
350+
* After the response is returned this method returns the response time in microseconds.
351+
* <p>
352+
* This is useful for use in {@link RequestIntercept#afterResponse(HttpResponse, HttpClientRequest)}
353+
*/
354+
long responseTimeMicros();
348355
}

http-client/client/src/main/java/io/avaje/http/client/RequestIntercept.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ public interface RequestIntercept {
1212
* <p>
1313
* Typically we can add headers or modify the request prior to it being sent.
1414
*/
15-
void beforeRequest(HttpClientRequest request);
15+
default void beforeRequest(HttpClientRequest request) {
16+
// do nothing by default
17+
}
1618

1719
/**
1820
* After the response has been received.
1921
*/
20-
void afterResponse(HttpResponse<?> response, HttpClientRequest request);
22+
default void afterResponse(HttpResponse<?> response, HttpClientRequest request) {
23+
// do nothing by default
24+
}
2125

2226
}

http-client/client/src/main/java/io/avaje/http/client/RequestListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ interface Event {
2525
/**
2626
* Return the time from request to response in nanos.
2727
*/
28-
long responseTimeNanos();
28+
long responseTimeMicros();
2929

3030
/**
3131
* Return the URI for the request.

http-client/client/src/main/java/io/avaje/http/client/RequestLogger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void response(Event event) {
4242
if (log.isDebugEnabled()) {
4343
final HttpResponse<?> response = event.response();
4444
final HttpRequest request = response.request();
45-
long micros = event.responseTimeNanos() / 1000;
45+
long micros = event.responseTimeMicros();
4646

4747
StringBuilder sb = new StringBuilder();
4848
sb.append("statusCode:").append(response.statusCode())

http-client/client/src/test/java/io/avaje/http/client/RequestListenerTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.avaje.http.client;
22

33
import com.fasterxml.jackson.databind.ObjectMapper;
4-
import org.example.webserver.HelloDto;
54
import org.junit.jupiter.api.Test;
65

76
import java.net.http.HttpResponse;
@@ -28,7 +27,7 @@ public void response(Event event) {
2827
assertThat(event.uri().toString()).isEqualTo("http://localhost:8887/hello/message");
2928
assertThat(event.requestBody()).isNull();
3029
}
31-
assertThat(event.responseTimeNanos()).isGreaterThan(1L);
30+
assertThat(event.responseTimeMicros()).isGreaterThan(1L);
3231
assertThat(event.response().statusCode()).isEqualTo(200);
3332
assertThat(event.request()).isEqualTo(event.response().request());
3433
}

http-client/client/src/test/java/io/avaje/http/client/RetryTest.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,43 @@
99

1010
public class RetryTest extends BaseWebTest {
1111

12+
final MyIntercept myIntercept = new MyIntercept();
1213
final HttpClientContext clientContext = initClientWithRetry();
1314

14-
static HttpClientContext initClientWithRetry() {
15+
HttpClientContext initClientWithRetry() {
1516
return HttpClientContext.newBuilder()
1617
.withBaseUrl("http://localhost:8887")
1718
.withBodyAdapter(new JacksonBodyAdapter(new ObjectMapper()))
1819
.withRequestListener(new RequestLogger())
1920
.withRetryHandler(new SimpleRetryHandler(4, 1))
21+
.withRequestIntercept(myIntercept)
2022
.build();
2123
}
2224

2325
@Test
2426
void retryTest() {
25-
2627
HttpResponse<String> res = clientContext.request()
2728
.path("hello/retry")
2829
.GET()
2930
.asString();
3031

3132
assertThat(res.body()).isEqualTo("All good at 3rd attempt");
33+
34+
assertThat(myIntercept.responseTimeMicros).isGreaterThan(1);
35+
assertThat(myIntercept.counter).isEqualTo(1);
3236
}
3337

38+
static class MyIntercept implements RequestIntercept {
39+
int counter;
40+
long responseTimeMicros;
41+
42+
/**
43+
* Not called for the retry attempts. Only called on the final success or error response.
44+
*/
45+
@Override
46+
public void afterResponse(HttpResponse<?> response, HttpClientRequest request) {
47+
counter++;
48+
responseTimeMicros = request.responseTimeMicros();
49+
}
50+
}
3451
}

0 commit comments

Comments
 (0)