2023-01-05 07:36:10 +00:00
|
|
|
from typing import Optional, Union
|
2022-09-08 01:08:37 +00:00
|
|
|
|
|
|
|
import fakeredis.aioredis
|
|
|
|
from redis import asyncio as aioredis
|
2022-11-25 10:02:18 +00:00
|
|
|
from redis.exceptions import ConnectionError as RedisConnectionError, TimeoutError as RedisTimeoutError
|
2022-09-08 01:08:37 +00:00
|
|
|
from typing_extensions import Self
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
from core.base_service import BaseService
|
|
|
|
from core.config import ApplicationConfig
|
2022-09-08 01:08:37 +00:00
|
|
|
from utils.log import logger
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
__all__ = ["RedisDB"]
|
2022-09-08 01:08:37 +00:00
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
|
|
|
|
class RedisDB(BaseService.Dependence):
|
2022-09-08 01:08:37 +00:00
|
|
|
@classmethod
|
2023-03-14 01:27:22 +00:00
|
|
|
def from_config(cls, config: ApplicationConfig) -> Self:
|
2022-09-08 01:08:37 +00:00
|
|
|
return cls(**config.redis.dict())
|
|
|
|
|
2023-01-05 07:36:10 +00:00
|
|
|
def __init__(
|
|
|
|
self, host: str = "127.0.0.1", port: int = 6379, database: Union[str, int] = 0, password: Optional[str] = None
|
|
|
|
):
|
|
|
|
self.client = aioredis.Redis(host=host, port=port, db=database, password=password)
|
2022-09-08 01:08:37 +00:00
|
|
|
self.ttl = 600
|
|
|
|
|
|
|
|
async def ping(self):
|
2023-03-14 01:27:22 +00:00
|
|
|
# noinspection PyUnresolvedReferences
|
2022-09-08 01:08:37 +00:00
|
|
|
if await self.client.ping():
|
2022-09-08 04:57:22 +00:00
|
|
|
logger.info("连接 [red]Redis[/] 成功", extra={"markup": True})
|
2022-09-08 01:08:37 +00:00
|
|
|
else:
|
2022-09-08 04:57:22 +00:00
|
|
|
logger.info("连接 [red]Redis[/] 失败", extra={"markup": True})
|
|
|
|
raise RuntimeError("连接 Redis 失败")
|
2022-09-08 01:08:37 +00:00
|
|
|
|
2022-11-25 10:02:18 +00:00
|
|
|
async def start_fake_redis(self):
|
|
|
|
self.client = fakeredis.aioredis.FakeRedis()
|
|
|
|
await self.ping()
|
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
async def initialize(self):
|
2022-09-08 04:57:22 +00:00
|
|
|
logger.info("正在尝试建立与 [red]Redis[/] 连接", extra={"markup": True})
|
2022-09-08 01:08:37 +00:00
|
|
|
try:
|
|
|
|
await self.ping()
|
2022-11-25 10:02:18 +00:00
|
|
|
except (RedisTimeoutError, RedisConnectionError) as exc:
|
|
|
|
if isinstance(exc, RedisTimeoutError):
|
|
|
|
logger.warning("连接 [red]Redis[/] 超时,使用 [red]fakeredis[/] 模拟", extra={"markup": True})
|
|
|
|
if isinstance(exc, RedisConnectionError):
|
|
|
|
logger.warning("连接 [red]Redis[/] 失败,使用 [red]fakeredis[/] 模拟", extra={"markup": True})
|
|
|
|
await self.start_fake_redis()
|
2022-09-08 01:08:37 +00:00
|
|
|
|
2023-03-14 01:27:22 +00:00
|
|
|
async def shutdown(self):
|
2022-09-08 01:08:37 +00:00
|
|
|
await self.client.close()
|