Skip to content

Do not buffer the Response stream using BufferedHttpEntity #6200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

joviegas
Copy link
Contributor

@joviegas joviegas commented Jun 21, 2025

Motivation and Context

Apache HttpClient 5.x automatically closes response streams after execution, causing premature connection closure when using execute() with response handlers. This differs from Apache 4.x behavior and can lead to connection pool issues. The previous implementation used BufferedHttpEntity to work around this, but it buffers the entire response in memory, causing performance issues for large responses.

Modifications

  • Removed automatic buffering of all HTTP responses using BufferedHttpEntity
  • Added proper handling for empty responses (Content-Length: 0) by immediately closing the connection and returning an empty ByteArrayInputStream
  • Refactored response creation to handle different response types more efficiently
  • Added getResponseBody() method to centralize response body handling logic

Testing

  • Added Junits and SdkBenchMark tests
Benchmark Apache4 (ops/s) Apache5 (ops/s) Difference Comment
concurrentApiCall 17865.137 ± 368.671 17765.843 ± 198.946 -99.294 Apache4 slightly faster, but difference is minimal (~0.6%)
concurrentStreamingOutputOperation 487.343 ± 10.050 483.503 ± 9.365 -3.840 Nearly identical performance (~0.8% difference)
concurrentStreamingPutOperation 135.945 ± 6.082 134.752 ± 6.417 -1.193 Negligible difference (~0.9%)
sequentialApiCall 2505.485 ± 45.366 2524.854 ± 34.044 +19.369 Apache5 slightly faster (~0.8% improvement)
streamingOutputOperation 88.866 ± 1.165 88.053 ± 0.814 -0.813 Essentially equivalent performance
streamingPutOperation 21.569 ± 0.069 21.409 ± 0.412 -0.160 No meaningful difference

Key Inference: Apache4 and Apache5 have virtually identical performance across all benchmarks. The differences are all under 1%, which is within normal variance and not statistically significant. The choice between them should be based on features, maintenance, and compatibility rather than performance.

Will create a separate test for performance benchmarking

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document
  • Local run of mvn install succeeds
  • My code follows the code style of this project
  • My change requires a change to the Javadoc documentation
  • I have updated the Javadoc documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added a changelog entry. Adding a new entry must be accomplished by running the scripts/new-change script and following the instructions. Commit the new file created by the script in .changes/next-release with your changes.
  • My change is to implement 1.11 parity feature and I have updated LaunchChangelog

License

  • I confirm that this pull request can be released under the Apache 2 license

joviegas and others added 17 commits May 29, 2025 09:55
… is implementation of HttpClientConnectionManager
…ring content reference to avoid multiple ContentStreamProvider.newStream() calls that cause IOException when retrying requests with non-resettable streams
…e is value is set to 0 since 0 is treated as Infinite timeToLive in Sdk and Apache 4.x but treated as immediate closeConnection in apache 5.x
…o define Apache5 dependencies in .brazil.json
…cause memory issue, this behaviour is same as Apache4.x
@joviegas joviegas requested a review from a team as a code owner June 21, 2025 01:42
@joviegas joviegas changed the title Do buffer the Response stream using BufferedHttpEntity Do not buffer the Response stream using BufferedHttpEntity Jun 21, 2025
@joviegas joviegas force-pushed the joviegas/apache-5-achitecture-test-fix branch from 3596705 to bb70f7d Compare June 21, 2025 04:29
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
65.6% Coverage on New Code (required ≥ 80%)
22.0% Duplication on New Code (required ≤ 3%)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Comment on lines +185 to +188
@Test
public void handlesVariousContentLengths() throws Exception {
SdkHttpClient client = createSdkHttpClient();
int[] contentLengths = {0, 1, 100, 1024, 65536};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason we don't use parameterized test instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test extends SdkHttpClientTestSuite which is based on Junit 4

@joviegas joviegas merged commit 3cedfb1 into feature/master/apache5x Jun 24, 2025
23 of 26 checks passed
Copy link

This pull request has been closed and the conversation has been locked. Comments on closed PRs are hard for our team to see. If you need more assistance, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants