[patch] Align Redis and MinIO connect() idempotency #37

Merged
brian merged 2 commits from cursor/connect-idempotency-alignment into main 2026-07-09 16:38:06 +02:00
Owner

Summary

Redis and MinIO adapters previously disagreed on connect() behavior: MinIO short-circuited when already healthy, while Redis always closed and recreated its client. That inconsistency was awkward for context-manager usage and defensive connect() calls.

This PR moves shared connect orchestration into ConnectionAwareAdapter:

  • Injected client — validate reachability, do not create or close the client
  • Already healthy — log "Already connected to {connection_name}" and return
  • Otherwisedisconnect(), then _establish_connection()

RedisAdapter and MinioAdapter now implement _validate_injected_client() and _establish_connection() instead of duplicating connect logic. The early-return guard uses _is_client_ready() so MinIO cannot falsely short-circuit without bucket context.

Docs updated in ConnectionAwareInterface and README.md to note that connect() is idempotent.

Test plan

  • uv run pytest tests/unit/redis_adapter_test.py tests/unit/minio_adapter_test.py tests/unit/connection_aware_adapter_test.py -q
  • uv run pytest tests/integration/redis_adapter_test.py tests/integration/minio_adapter_test.py -m integration -q
  • Added unit tests for idempotent skip and unhealthy reconnect paths (Redis + MinIO)
  • Added Redis integration test mirroring existing MinIO "already connected" log assertion
## Summary Redis and MinIO adapters previously disagreed on `connect()` behavior: MinIO short-circuited when already healthy, while Redis always closed and recreated its client. That inconsistency was awkward for context-manager usage and defensive `connect()` calls. This PR moves shared connect orchestration into `ConnectionAwareAdapter`: - **Injected client** — validate reachability, do not create or close the client - **Already healthy** — log `"Already connected to {connection_name}"` and return - **Otherwise** — `disconnect()`, then `_establish_connection()` `RedisAdapter` and `MinioAdapter` now implement `_validate_injected_client()` and `_establish_connection()` instead of duplicating connect logic. The early-return guard uses `_is_client_ready()` so MinIO cannot falsely short-circuit without bucket context. Docs updated in `ConnectionAwareInterface` and `README.md` to note that `connect()` is idempotent. ## Test plan - [x] `uv run pytest tests/unit/redis_adapter_test.py tests/unit/minio_adapter_test.py tests/unit/connection_aware_adapter_test.py -q` - [x] `uv run pytest tests/integration/redis_adapter_test.py tests/integration/minio_adapter_test.py -m integration -q` - [x] Added unit tests for idempotent skip and unhealthy reconnect paths (Redis + MinIO) - [x] Added Redis integration test mirroring existing MinIO "already connected" log assertion
brian added 1 commit 2026-07-09 15:52:51 +02:00
Align Redis and MinIO connect() idempotency in ConnectionAwareAdapter.
PR Title Check / check-title (pull_request) Successful in 5s
Test Python Package / unit-tests (pull_request) Successful in 13s
Test Python Package / integration-tests (pull_request) Successful in 30s
Test Python Package / coverage-report (pull_request) Failing after 15s
Code Quality Pipeline / code-quality (pull_request) Successful in 53s
67bb88fbb4
Move shared connect orchestration into the base adapter so both backends short-circuit when already healthy and only reconnect after a failed probe.

Co-authored-by: Cursor <cursoragent@cursor.com>
brian added 1 commit 2026-07-09 15:57:12 +02:00
Cover injected-client connect when client was cleared by disconnect.
PR Title Check / check-title (pull_request) Successful in 5s
Code Quality Pipeline / code-quality (pull_request) Successful in 26s
Test Python Package / integration-tests (pull_request) Successful in 1m5s
Test Python Package / unit-tests (pull_request) Successful in 29s
Test Python Package / coverage-report (pull_request) Successful in 41s
b8d88e6703
Restore 100% coverage for the _validate_injected_client early-return paths in Redis and MinIO adapters.

Co-authored-by: Cursor <cursoragent@cursor.com>
Member

Test Coverage Report:

Name                                                            Stmts   Miss    Cover   Missing
-----------------------------------------------------------------------------------------------
python_repositories/__init__.py                                    12      0  100.00%
python_repositories/adapters/__init__.py                           13      0  100.00%
python_repositories/adapters/connection_aware_adapter.py           61      0  100.00%
python_repositories/adapters/minio_adapter.py                     117      0  100.00%
python_repositories/adapters/redis_adapter.py                     105      0  100.00%
python_repositories/config/__init__.py                              4      0  100.00%
python_repositories/config/dotenv_loader.py                         7      0  100.00%
python_repositories/config/env_bool.py                             14      0  100.00%
python_repositories/config/minio_config.py                         21      0  100.00%
python_repositories/config/redis_config.py                         14      0  100.00%
python_repositories/examples/__init__.py                            0      0  100.00%
python_repositories/examples/artifact_object_repository.py          9      0  100.00%
python_repositories/examples/user_json_repository.py               10      0  100.00%
python_repositories/interfaces/__init__.py                          5      0  100.00%
python_repositories/interfaces/connection_aware_interface.py        8      0  100.00%
python_repositories/interfaces/context_aware_interface.py           8      0  100.00%
python_repositories/interfaces/json_repository_interface.py        14      0  100.00%
python_repositories/interfaces/object_repository_interface.py      11      0  100.00%
-----------------------------------------------------------------------------------------------
TOTAL                                                             433      0  100.00%

**Test Coverage Report:** ``` Name Stmts Miss Cover Missing ----------------------------------------------------------------------------------------------- python_repositories/__init__.py 12 0 100.00% python_repositories/adapters/__init__.py 13 0 100.00% python_repositories/adapters/connection_aware_adapter.py 61 0 100.00% python_repositories/adapters/minio_adapter.py 117 0 100.00% python_repositories/adapters/redis_adapter.py 105 0 100.00% python_repositories/config/__init__.py 4 0 100.00% python_repositories/config/dotenv_loader.py 7 0 100.00% python_repositories/config/env_bool.py 14 0 100.00% python_repositories/config/minio_config.py 21 0 100.00% python_repositories/config/redis_config.py 14 0 100.00% python_repositories/examples/__init__.py 0 0 100.00% python_repositories/examples/artifact_object_repository.py 9 0 100.00% python_repositories/examples/user_json_repository.py 10 0 100.00% python_repositories/interfaces/__init__.py 5 0 100.00% python_repositories/interfaces/connection_aware_interface.py 8 0 100.00% python_repositories/interfaces/context_aware_interface.py 8 0 100.00% python_repositories/interfaces/json_repository_interface.py 14 0 100.00% python_repositories/interfaces/object_repository_interface.py 11 0 100.00% ----------------------------------------------------------------------------------------------- TOTAL 433 0 100.00% ```
brian merged commit 3dc412cd15 into main 2026-07-09 16:38:06 +02:00
brian deleted branch cursor/connect-idempotency-alignment 2026-07-09 16:38:07 +02:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lille-vemmelund/python-repositories#37