PYTHON-5272 Implement TLS session resumption for sync pool#2864
Draft
blink1073 wants to merge 10 commits into
Draft
PYTHON-5272 Implement TLS session resumption for sync pool#2864blink1073 wants to merge 10 commits into
blink1073 wants to merge 10 commits into
Conversation
Add _SSLSessionCache to cache TLS sessions per pool, enabling session resumption on subsequent connections to the same server. This avoids full asymmetric-key handshakes on every new connection, addressing the OpenSSL 3.0 performance overhead seen in BF-36991.
Verify that a pre-populated _SSLSessionCache passes the cached session as session= to wrap_socket on the next connection, using mocks so no live server is required.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
On Python 3.11+, SSLProtocol.__init__ creates the ssl.SSLObject via
wrap_bio before the handshake starts in connection_made. We temporarily
replace asyncio.sslproto.SSLProtocol with a subclass that sets
sslobj.session to the cached session immediately after super().__init__,
then restore the original class. With a pre-connected sock= parameter,
_make_ssl_transport is called synchronously inside create_connection
before the first await, so the swap is race-free in a single-threaded
event loop.
After the handshake, the session is retrieved via
transport.get_extra_info('ssl_object').session and stored in the pool's
_SSLSessionCache for the next connection.
Capture _ORIGINAL_SSL_PROTOCOL once at module load time and always restore to it unconditionally, so that concurrent connections from the same pool cannot leave a stale SSLProtocol subclass active in asyncio.sslproto.
Module-level import of asyncio.sslproto on PyPy 3.11 changed GC timing and surfaced a pre-existing unclosed-socket ResourceWarning as a test error. Use a module-level None sentinel instead and initialise it on first use inside the function, which keeps the import lazy while still capturing the true original SSLProtocol before any patching occurs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PYTHON-5272
Changes in this PR
Added TLS session resumption to the connection pool, avoiding a full handshake on each new connection to the same server. Session reuse is active on the sync path unconditionally, and on the async path on Python 3.11 or later.
Test Plan
Added unit and integration tests covering:
_SSLSessionCacheget/set behaviorwrap_socketon subsequent connections (sync, no server required)SSLObjectbefore the handshake on Python 3.11+ (async, no server required)Checklist
Checklist for Author
Checklist for Reviewer