From 31b41ee30d83d993daf51373a75028a33d94eceb Mon Sep 17 00:00:00 2001 From: David Schlosnagle Date: Mon, 12 May 2025 18:40:42 -0400 Subject: [PATCH 1/2] Optimize DialogueFeignClient small response reader Avoid InputStreamReader / HeapByteBuffer overhead for small (less than 8KiB) inputs, see https://github.com/FasterXML/jackson-core/pull/1081 --- .../java/client/jaxrs/DialogueFeignClient.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java b/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java index aebb26f2d..042b4e026 100644 --- a/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java +++ b/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java @@ -43,6 +43,7 @@ import com.palantir.logsafe.UnsafeArg; import com.palantir.logsafe.exceptions.SafeIllegalStateException; import com.palantir.logsafe.exceptions.SafeRuntimeException; +import com.palantir.logsafe.exceptions.SafeUncheckedIoException; import feign.Request; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -50,6 +51,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; +import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; @@ -239,6 +241,18 @@ public InputStream asInputStream() { @Override public Reader asReader() { + Integer maybeLength = length(); + if (maybeLength != null && maybeLength.intValue() < 8192) { + // Avoid InputStreamReader / HeapByteBuffer overhead for small (less than 8KiB) inputs, + // see https://github.com/FasterXML/jackson-core/pull/1081 + try (InputStream inputStream = asInputStream()) { + String content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + return new StringReader(content); + } catch (IOException e) { + throw new SafeUncheckedIoException( + "Failed to read response body", e, SafeArg.of("length", maybeLength)); + } + } return new InputStreamReader(asInputStream(), StandardCharsets.UTF_8); } From e33697111b970e603c5327785df7b8ede1d7b0ed Mon Sep 17 00:00:00 2001 From: David Schlosnagle Date: Mon, 12 May 2025 22:32:49 -0400 Subject: [PATCH 2/2] tweak --- .../java/client/jaxrs/DialogueFeignClient.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java b/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java index 042b4e026..5751bd746 100644 --- a/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java +++ b/conjure-java-jaxrs-client/src/main/java/com/palantir/conjure/java/client/jaxrs/DialogueFeignClient.java @@ -52,7 +52,6 @@ import java.io.OutputStream; import java.io.Reader; import java.io.StringReader; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.Collection; @@ -145,11 +144,7 @@ private static boolean includeRequestHeader(String headerName) { } private static String urlDecode(String input) { - try { - return URLDecoder.decode(input, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new SafeRuntimeException("Failed to decode path segment", e, UnsafeArg.of("encoded", input)); - } + return URLDecoder.decode(input, StandardCharsets.UTF_8); } private static Optional requestBody(Request request) { @@ -242,12 +237,11 @@ public InputStream asInputStream() { @Override public Reader asReader() { Integer maybeLength = length(); - if (maybeLength != null && maybeLength.intValue() < 8192) { + if (maybeLength != null && maybeLength < 8192) { // Avoid InputStreamReader / HeapByteBuffer overhead for small (less than 8KiB) inputs, // see https://github.com/FasterXML/jackson-core/pull/1081 try (InputStream inputStream = asInputStream()) { - String content = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); - return new StringReader(content); + return new StringReader(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8)); } catch (IOException e) { throw new SafeUncheckedIoException( "Failed to read response body", e, SafeArg.of("length", maybeLength));