Skip to content

The dishka provider asks for Redis, redis-client-kit provides Redis | RedisCluster: the container never builds #32

Description

@AlexeyShalaev

The shipped dishka provider asks for redis.asyncio.Redis, redis-client-kit provides
Redis | RedisCluster — a container registering both never builds.

What happens

idempotency_kit.dishka.aio.redis requests the concrete client:

from redis.asyncio import Redis as AsyncRedisClient
...
def get_repository(self, redis: AsyncRedisClient, ...) -> AsyncIdempotencyRepository: ...

redis_client_kit.providers.AsyncRedisProvider provides the union its own alias names:

>>> from redis_client_kit import AsyncRedisClient
>>> AsyncRedisClient
redis.asyncio.client.Redis | redis.asyncio.cluster.RedisCluster

dishka resolves by exact key, so the two do not meet:

make_async_container(
    AsyncRedisProvider(),              # provides Redis | RedisCluster
    AsyncRedisIdempotencyProvider(),   # requests Redis
    ...
)
# dishka.exceptions.GraphMissingFactoryError:
#   Cannot find factory for (Redis, component=''). It is missing or has invalid scope.

No Redis server is needed to reproduce — it fails at container construction.

Why it matters

These are the two libraries in the ecosystem that both talk to Redis and both ship dishka providers,
so a service using idempotency with the kit's Redis client is the expected combination, and it is
exactly the one that cannot be wired from the shipped pieces. The failure is at least loud, but the
only ways out are to keep a private provider (what we do), or to register a bridge that claims a
RedisCluster is a Redis, which is a lie the day someone enables cluster mode.

We have kept a local Redis-plus-idempotency provider pair in a 14-service monorepo for this reason
alone; every other provider in that package has been replaced by a shipped one.

What would help

Whatever makes the two keys meet without a consumer-side adapter. Options we can see:

  • accept the union (or a structural protocol covering the commands the repository actually issues),
    so a cluster client is either genuinely supported or rejected with a clear message;
  • state that the repository requires a non-cluster Redis and provide a supported way to narrow
    the union, so the cast happens once, here, with the check attached;
  • agree a shared alias between the two libraries.

The design call is yours — a cluster-mode Redis may well not be supportable by a repository that
uses multi-key operations, and if so that constraint is worth expressing in the type rather than
discovered at runtime.

Cross-reference: redis-client-kit owns the other half of this key, redis_client_kit.providers.

Versions

idempotency-kit 0.3.0, redis-client-kit 0.2.0, dishka 1.9.1, redis 7.4.0, CPython 3.14.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions