70 lines
1.8 KiB
Python
70 lines
1.8 KiB
Python
from abc import abstractmethod
|
|
from typing import Optional, Union
|
|
|
|
from redis.asyncio import Redis, RedisCluster
|
|
from redis.data_structure import WeightedList
|
|
from redis.multidb.circuit import CircuitBreaker
|
|
from redis.multidb.database import AbstractDatabase, BaseDatabase
|
|
from redis.typing import Number
|
|
|
|
|
|
class AsyncDatabase(AbstractDatabase):
|
|
"""Database with an underlying asynchronous redis client."""
|
|
|
|
@property
|
|
@abstractmethod
|
|
def client(self) -> Union[Redis, RedisCluster]:
|
|
"""The underlying redis client."""
|
|
pass
|
|
|
|
@client.setter
|
|
@abstractmethod
|
|
def client(self, client: Union[Redis, RedisCluster]):
|
|
"""Set the underlying redis client."""
|
|
pass
|
|
|
|
@property
|
|
@abstractmethod
|
|
def circuit(self) -> CircuitBreaker:
|
|
"""Circuit breaker for the current database."""
|
|
pass
|
|
|
|
@circuit.setter
|
|
@abstractmethod
|
|
def circuit(self, circuit: CircuitBreaker):
|
|
"""Set the circuit breaker for the current database."""
|
|
pass
|
|
|
|
|
|
Databases = WeightedList[tuple[AsyncDatabase, Number]]
|
|
|
|
|
|
class Database(BaseDatabase, AsyncDatabase):
|
|
def __init__(
|
|
self,
|
|
client: Union[Redis, RedisCluster],
|
|
circuit: CircuitBreaker,
|
|
weight: float,
|
|
health_check_url: Optional[str] = None,
|
|
):
|
|
self._client = client
|
|
self._cb = circuit
|
|
self._cb.database = self
|
|
super().__init__(weight, health_check_url)
|
|
|
|
@property
|
|
def client(self) -> Union[Redis, RedisCluster]:
|
|
return self._client
|
|
|
|
@client.setter
|
|
def client(self, client: Union[Redis, RedisCluster]):
|
|
self._client = client
|
|
|
|
@property
|
|
def circuit(self) -> CircuitBreaker:
|
|
return self._cb
|
|
|
|
@circuit.setter
|
|
def circuit(self, circuit: CircuitBreaker):
|
|
self._cb = circuit
|