From 224819ea119b718cf40037ecfed47fc2b8d92517 Mon Sep 17 00:00:00 2001 From: LWR Date: Mon, 1 Apr 2024 01:32:46 +0800 Subject: [PATCH] refactor: Optimized auto reload task in JsonDataSource --- starbot_datasource/__init__.py | 5 +-- starbot_datasource/core/datasource.py | 46 ++++++++++++++++++++------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/starbot_datasource/__init__.py b/starbot_datasource/__init__.py index b44558a..0a877d5 100644 --- a/starbot_datasource/__init__.py +++ b/starbot_datasource/__init__.py @@ -1,2 +1,3 @@ -from .core.event import * -from .core.datasource import * +from .core.event import EventType, DataSourceEvent +from .core.datasource import DataSource, DictDataSource, JsonDataSource +from .core.config import config \ No newline at end of file diff --git a/starbot_datasource/core/datasource.py b/starbot_datasource/core/datasource.py index aa2eb2b..6137366 100644 --- a/starbot_datasource/core/datasource.py +++ b/starbot_datasource/core/datasource.py @@ -1,6 +1,8 @@ import abc import asyncio import json +import os +from json import JSONDecodeError from typing import List, Dict, Union, Optional, NoReturn, Set from loguru import logger @@ -124,7 +126,6 @@ class JsonDataSource(DataSource): def __init__(self, json_file: str, auto_reload: Optional[bool] = True, auto_reload_interval: Optional[int] = 5): super().__init__() self.__config = None - self.__content = "" self.__json_file = json_file self.__auto_reload = auto_reload @@ -141,8 +142,9 @@ async def load(self) -> NoReturn: logger.info("开始从 JSON 中初始化 Bot 配置") try: + modify_time = os.path.getmtime(self.__json_file) with open(self.__json_file, encoding="utf-8") as file: - self.__content = file.read() + content = file.read() except FileNotFoundError: raise DataSourceException("JSON 文件不存在, 请检查文件路径是否正确") except UnicodeDecodeError: @@ -151,7 +153,7 @@ async def load(self) -> NoReturn: raise DataSourceException(f"读取 JSON 文件异常 {ex}") try: - self.__config = json.loads(self.__content) + self.__config = json.loads(content) except Exception: raise DataSourceException("JSON 文件内容格式不正确") @@ -167,21 +169,30 @@ async def load(self) -> NoReturn: logger.success(f"成功从 JSON 中导入了 {len(self.ups)} 个 UP 主") if self.__auto_reload: - executor.create_task(self.__auto_reload_task()) + executor.create_task(self.__auto_reload_task(modify_time)) - async def __auto_reload_task(self) -> NoReturn: + async def __auto_reload_task(self, modify_time: float) -> NoReturn: """ JSON 文件内容发生变化时自动重载配置 + + Args: + modify_time: 配置文件修改时间 """ while True: await asyncio.sleep(self.__auto_reload_interval) try: - with open(self.__json_file, encoding="utf-8") as file: - content = file.read() + new_modify_time = os.path.getmtime(self.__json_file) - if content == self.__content: + if new_modify_time == modify_time: continue + modify_time = new_modify_time + + logger.info(f"数据源配置已更新, 开始重载配置") + + with open(self.__json_file, encoding="utf-8") as file: + content = file.read() + conf = json.loads(content) if isinstance(conf, dict): conf = [conf] @@ -194,7 +205,6 @@ async def __auto_reload_task(self) -> NoReturn: if len(new_up_set) != len(new_ups): raise DataSourceException("数据源中不可含有重复的主播") - self.__content = content self.__config = conf added_ups = new_up_set - self.ups @@ -202,9 +212,9 @@ async def __auto_reload_task(self) -> NoReturn: tip = [f'{act}了 {len(ups)} 个主播' for act, ups in [('新增', added_ups), ('移除', removed_ups)] if ups] if tip: - logger.info(f"检测到数据源配置中 {', '.join(tip)}") + logger.info(f"检测到 {', '.join(tip)}") else: - logger.info(f"检测到数据源配置已更新, 开始重载配置") + logger.info("未检测到新增或移除的主播, 开始重载已存在主播的配置") for up in new_up_set.union(self.ups): if up in added_ups: @@ -213,5 +223,17 @@ async def __auto_reload_task(self) -> NoReturn: self.remove(up.uid) else: self.update(up) - except Exception: + + logger.success("数据源配置重载成功") + except FileNotFoundError: + logger.error("数据源配置 JSON 文件不存在") + except UnicodeDecodeError: + logger.error("数据源配置 JSON 文件编码不正确, 请将其转换为 UTF-8 格式编码") + except JSONDecodeError: + logger.error("数据源配置 JSON 文件内容格式不正确") + except DataSourceException as ex: + logger.error(ex.msg) + except Exception as ex: + logger.error(f"数据源自动重载任务异常 {ex}") + finally: continue