summit/backend/venv/lib/python3.12/site-packages/redis/multidb/database.py

131 lines
3.5 KiB
Python

from abc import ABC, abstractmethod
from typing import Optional, Union
import redis
from redis import RedisCluster
from redis.data_structure import WeightedList
from redis.multidb.circuit import CircuitBreaker
from redis.typing import Number
class AbstractDatabase(ABC):
@property
@abstractmethod
def weight(self) -> float:
"""The weight of this database in compare to others. Used to determine the database failover to."""
pass
@weight.setter
@abstractmethod
def weight(self, weight: float):
"""Set the weight of this database in compare to others."""
pass
@property
@abstractmethod
def health_check_url(self) -> Optional[str]:
"""Health check URL associated with the current database."""
pass
@health_check_url.setter
@abstractmethod
def health_check_url(self, health_check_url: Optional[str]):
"""Set the health check URL associated with the current database."""
pass
class BaseDatabase(AbstractDatabase):
def __init__(
self,
weight: float,
health_check_url: Optional[str] = None,
):
self._weight = weight
self._health_check_url = health_check_url
@property
def weight(self) -> float:
return self._weight
@weight.setter
def weight(self, weight: float):
self._weight = weight
@property
def health_check_url(self) -> Optional[str]:
return self._health_check_url
@health_check_url.setter
def health_check_url(self, health_check_url: Optional[str]):
self._health_check_url = health_check_url
class SyncDatabase(AbstractDatabase):
"""Database with an underlying synchronous redis client."""
@property
@abstractmethod
def client(self) -> Union[redis.Redis, RedisCluster]:
"""The underlying redis client."""
pass
@client.setter
@abstractmethod
def client(self, client: Union[redis.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[SyncDatabase, Number]]
class Database(BaseDatabase, SyncDatabase):
def __init__(
self,
client: Union[redis.Redis, RedisCluster],
circuit: CircuitBreaker,
weight: float,
health_check_url: Optional[str] = None,
):
"""
Initialize a new Database instance.
Args:
client: Underlying Redis client instance for database operations
circuit: Circuit breaker for handling database failures
weight: Weight value used for database failover prioritization
health_check_url: Health check URL associated with the current database
"""
self._client = client
self._cb = circuit
self._cb.database = self
super().__init__(weight, health_check_url)
@property
def client(self) -> Union[redis.Redis, RedisCluster]:
return self._client
@client.setter
def client(self, client: Union[redis.Redis, RedisCluster]):
self._client = client
@property
def circuit(self) -> CircuitBreaker:
return self._cb
@circuit.setter
def circuit(self, circuit: CircuitBreaker):
self._cb = circuit