Skip to content

fix(connection): convert TLS and unix-socket clients to async - #792

Open
Yarmoluk wants to merge 1 commit into
redis:mainfrom
Yarmoluk:fix/sync-to-async-connection-classes
Open

Yarmoluk wants to merge 1 commit into
redis:mainfrom
Yarmoluk:fix/sync-to-async-connection-classes

Conversation

@Yarmoluk

@Yarmoluk Yarmoluk commented Oct 27, 2026 •

Copy link
Copy Markdown

Closes #789.

Motivation

RedisConnectionFactory.sync_to_async_redis passed the sync pool's connection_kwargs straight into AsyncConnectionPool and picked the TLS class with an exact-type check. A client built with Redis(ssl=True, ...), Redis(unix_socket_path=...) or Sentinel.master_for(...) therefore raised TypeError on its first async command (SemanticCache.acheck, and SemanticRouter.aroute once #784 lands), and a subclass of SSLConnection got a plaintext async connection with the password still set.

Changes

  • The async connection class is chosen with issubclass: TLS connections (and subclasses) map to AsyncSSLConnection, unix-socket connections to the async UnixDomainSocketConnection, everything else to AsyncConnection.
  • _async_connection_kwargs keeps only the keywords the chosen async class accepts, found by walking its __init__ chain (_accepted_init_kwargs), so the filter follows whatever redis-py version is installed rather than a hard-coded key list. A sync-only keyword at its default (None or False) is dropped; one that is set, such as ssl_validate_ocsp=True, raises a ValueError naming it, because the async client cannot honour it and dropping it would silently weaken TLS verification.
  • Sentinel-managed pools are rejected up front with a clear ValueError, as RedisCluster already was.
  • Seven unit tests in tests/unit/test_sync_to_async_redis.py, none needing a server; five fail on main.

Release Notes

SemanticCache, AsyncSearchIndex and any other async path that converts a caller's sync client now work with clients configured with TLS keywords (Redis(ssl=True, ...)), unix sockets, and custom SSLConnection subclasses. Sentinel-managed clients, RedisCluster clients, and clients with a sync-only setting enabled (OCSP validation) raise ValueError at conversion time with a pointer to redis_url; previously they failed with TypeError on the first command.

Reviewer Brief

Start here: redisvl/redis/connection.py, _async_connection_kwargs. It decides which of the sync pool's settings reach the async connection and which abort the conversion; sync_to_async_redis only picks the class and calls it.

Where it could fail

  • redisvl/redis/connection.py:350: a sync-only keyword whose default is not None or False (none exist in redis-py 6.3.0 through 8.1.0) would make every conversion raise; check the value not in (None, False) test against any new keyword a future redis-py adds.
  • redisvl/redis/connection.py:328: _accepted_init_kwargs stops at the first __init__ without **kwargs; if redis-py ever adds keywords below AbstractConnection in the chain they would be dropped as unaccepted.

Not verified: cluster mode (unchanged path, raises as before); a live TLS or unix-socket server (the tests stop at make_connection(), where every reported failure occurred).

Beyond CI: the seven new tests pass on redis-py 8.1.0 and on 6.3.0, the floor in pyproject.toml; five of them fail on main. tests/integration/test_llmcache.py, test_embedcache.py and test_async_search_index.py: 140 passed (Redis 8.4 via the repo's testcontainers compose); tests/unit: 1823 passed.

Reviewed d23003e · Claude Code (claude-fable-5-1) · lenses: correctness, security, design, tests, docs

Notes

🤖 Generated with Claude Code


Note

Medium Risk
Touches connection/TLS conversion used by async cache and index paths; incorrect kwarg handling could weaken TLS or break conversion, though sync-only enabled options now fail loudly instead of silently.

Overview
RedisConnectionFactory.sync_to_async_redis now builds async clients from sync pool settings instead of blindly copying connection_kwargs and using an exact SSLConnection type check.

Connection class selection uses issubclass: TLS (including custom SSLConnection subclasses) → AsyncSSLConnection, unix sockets → AsyncUnixDomainSocketConnection, otherwise AsyncConnection. _async_connection_kwargs filters kwargs by introspecting the async connection class’s __init__ chain; sync-only keys at default (None/False) are dropped, but non-default sync-only settings (e.g. ssl_validate_ocsp=True) raise ValueError so TLS options are not silently weakened. Sentinel-managed pools are rejected up front with a clear error, like RedisCluster.

Seven unit tests cover plain/TLS/URL/unix/Sentinel/OCSP cases without a live Redis server.

Reviewed by Cursor Bugbot for commit d23003e. Bugbot is set up for automated code reviews on this repo. Configure here.

sync_to_async_redis passed the sync pool's connection_kwargs straight to
the async pool and picked the TLS class with an exact-type check, so a
client built with Redis(ssl=True, ...), Redis(unix_socket_path=...) or
Sentinel.master_for(...) raised TypeError on its first async command,
and a subclass of SSLConnection got a plaintext async connection.

The async connection class is now chosen with issubclass for TLS and
unix-socket connections, keywords the async class does not accept are
dropped when they hold their default, a sync-only setting that is set
(such as OCSP validation) raises a clear ValueError instead of being
lost, and Sentinel-managed pools are rejected up front like RedisCluster.

Closes redis#789

This branch has not been deployed

No deployments
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.

sync_to_async_redis fails for TLS clients configured with keywords

1 participant