connection: tolerate clean startup close - #944
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Restores pre-3.29.11 handling of clean server-side closes during connection startup.
Changes:
- Returns cleanly closed startup connections to their owner.
- Adds regression coverage for this behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
cassandra/connection.py |
Removes immediate ConnectionShutdown for clean startup closes. |
tests/unit/test_connection.py |
Tests returning a cleanly closed connection. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| else: | ||
| return conn |
dc80701 to
fc09951
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
cassandra/connection.py:990
- Returning a closed connection is treated as a successful reconnect by existing owners.
_ReconnectionHandler.run()invokeson_reconnection()and its callback for any returned value (cassandra/pool.py:281-305), and_HostReconnectionHandlerthen marks the host up (cassandra/pool.py:353-361); initial pool construction likewise installs the returned connection without checkingis_closed(cassandra/pool.py:429-431). A clean startup close can therefore falsely mark a maintenance-mode host up and build a pool around a closed socket instead of preserving reconnection cadence. The owning paths need explicit closed-result handling (with coverage), or the factory needs a distinct failure/result contract.
else:
return conn
Summary
Fixes #942.
Version 3.29.11 started raising
ConnectionShutdownfromConnection.factory()when the server closed the socket during startup without settinglast_error. That made a clean server-side close look like an immediate connection-factory failure instead of leaving it to the owning pool/control connection path.Scylla maintenance mode has the same socket shape for regular CQL: it can accept the TCP connection, receive the first CQL startup frame, and close it because regular CQL is unavailable while the maintenance socket remains usable. This restores the pre-3.29.11 factory behavior for that clean startup close while keeping actual startup errors and timeouts unchanged.
Reproducer
Added
test_factory_returns_maintenance_mode_clean_startup_close, which starts a real local TCP listener that behaves like maintenance-mode regular CQL:OPTIONSframeWith the 3.29.11
elif conn.is_closedfactory check temporarily restored, this test fails with:With this PR, the same test passes and the closed connection is returned to the owning path.
Driver surface
Touches connection startup behavior only. No protocol serialization, query execution, metadata, or reactor code changed.
Compatibility / risk
Low but behavior-visible: clean server-side close during startup no longer raises directly from
Connection.factory(). Callers receive the closed connection and existing pool/control-connection handling decides host state and reconnection cadence, matching behavior before 3.29.11.Tests
uv run pytest -rf tests/unit/test_connection.py tests/unit/test_host_connection_pool.pyTZ=UTC uv run pytest -rf tests/unitNote: full unit suite without
TZ=UTCstill has an unrelated timezone-sensitive failure intests/unit/test_types.py::DateRangeDeserializationTests::test_deserialize_date_range_yearin this environment.