Skip to content

Conversation

TsengX
Copy link

@TsengX TsengX commented Oct 9, 2025

  • Add support for external HttpClient instances in HttpClientStreamableHttpTransport and HttpClientSseClientTransport builders
  • Implement proper HttpClient resource cleanup using reflection to close SelectorManager threads
  • Add shouldCloseHttpClient flag to control resource management lifecycle
  • Prevent thread leaks caused by unclosed HttpClient instances created via HttpClient.Builder.build()
  • Add comprehensive tests for external HttpClient usage and resource cleanup

Fixes thread accumulation issue where HttpClient-xxxx-SelectorManager threads would continuously grow, leading to memory exhaustion. This addresses the underlying JDK issue documented in JDK-8308364.

Related: https://bugs.openjdk.org/browse/JDK-8308364

Motivation and Context

The HttpClientStreamableHttpTransport and HttpClientSseClientTransport classes create new HttpClient instances via HttpClient.Builder.build() without properly managing their lifecycle. This leads to accumulation of HttpClient-xxxx-SelectorManager threads that are never cleaned up, eventually causing memory exhaustion.

Root cause analysis traced this to the OpenJDK 17 HttpClientImpl implementation (JDK-8308364), where each HttpClient spawns dedicated SelectorManager threads for network I/O but lacks public APIs for proper resource cleanup.

This change introduces two solutions:

  1. External HttpClient support - Allow users to provide pre-created HttpClient instances for resource sharing across multiple transports
  2. Automatic resource cleanup - Properly clean up internally-created HttpClient resources using reflection to access internal components

References

How Has This Been Tested?

  • Added tests for external HttpClient usage in HttpClientStreamableHttpSyncClientTests and HttpSseMcpSyncClientTests
  • Updated existing transport test to verify proper resource cleanup during graceful shutdown
  • Verified backward compatibility with existing test suite
  • All existing tests continue to pass without modification

Breaking Changes

No breaking changes. This is an additive change that maintains full API compatibility. Existing code will continue to work as before, but will now benefit from proper resource management and the option to use external HttpClient instances.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

- Add support for external HttpClient instances in HttpClientStreamableHttpTransport and HttpClientSseClientTransport builders
- Implement proper HttpClient resource cleanup using reflection to close SelectorManager threads
- Add shouldCloseHttpClient flag to control resource management lifecycle
- Prevent thread leaks caused by unclosed HttpClient instances created via HttpClient.Builder.build()
- Add comprehensive tests for external HttpClient usage and resource cleanup

Fixes thread accumulation issue where HttpClient-xxxx-SelectorManager threads
would continuously grow, leading to memory exhaustion. This addresses the
underlying JDK issue documented in JDK-8308364.

Related: https://bugs.openjdk.org/browse/JDK-8308364
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant