From bdc32b26fe80cd56fe0783af7005ab3e785fe4ce Mon Sep 17 00:00:00 2001 From: snowykami Date: Sun, 1 Sep 2024 13:22:12 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20[plugin]:=20=E6=9A=82=E6=97=B6=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E8=BD=BB=E9=9B=AA=E6=8E=A8=E9=80=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- liteyuki/bot/__init__.py | 35 ++++---------- liteyuki/bot/lifespan.py | 8 ++-- liteyuki/core/manager.py | 19 ++++---- src/liteyuki_plugins/lifespan_monitor.py | 5 +- .../liteyukibot_plugin_nonebot/__init__.py | 10 ++-- .../liteyukibot_plugin_nonebot/py.typed | 0 src/nonebot_plugins/to_liteyuki.py | 46 +++++++++---------- 7 files changed, 52 insertions(+), 71 deletions(-) create mode 100644 src/liteyuki_plugins/liteyukibot_plugin_nonebot/py.typed diff --git a/liteyuki/bot/__init__.py b/liteyuki/bot/__init__.py index f984d11f..de6fba42 100644 --- a/liteyuki/bot/__init__.py +++ b/liteyuki/bot/__init__.py @@ -55,17 +55,11 @@ class LiteyukiBot: """加载插件加载器""" load_plugin("liteyuki.plugins.plugin_loader") # 加载轻雪插件 - """信号处理""" - signal.signal(signal.SIGINT, self._handle_exit) - signal.signal(signal.SIGTERM, self._handle_exit) - atexit.register(self.process_manager.terminate_all) # 注册退出时的函数 - async def _run(self): """ 启动逻辑 """ await self.lifespan.before_start() # 启动前钩子 - await self.process_manager.start_all() await self.lifespan.after_start() # 启动后钩子 await self.keep_alive() @@ -73,35 +67,26 @@ class LiteyukiBot: """ 外部启动接口 """ + self.process_manager.start_all() try: asyncio.run(self._run()) except KeyboardInterrupt: - logger.info("Liteyuki is stopping...") + logger.opt(colors=True).info("Liteyuki is stopping...") + self.stop() + logger.opt(colors=True).info("Liteyuki is stopped...") async def keep_alive(self): """ 保持轻雪运行 """ + logger.info("Liteyuki is keeping alive...") try: while not self.stop_event.is_set(): - time.sleep(0.5) - except KeyboardInterrupt: - logger.info("Liteyuki is stopping...") + await asyncio.sleep(0.1) + except Exception: + logger.info("Liteyuki is exiting...") self.stop() - def _handle_exit(self, signum, frame): - """ - @litedoc-hide - - 信号处理 - Args: - signum: 信号 - frame: 帧 - """ - logger.info("Received signal, stopping all processes.") - self.stop() - sys.exit(0) - def restart(self, delay: int = 0): """ 重启轻雪本体 @@ -123,7 +108,7 @@ class LiteyukiBot: cmd = "nohup" self.process_manager.terminate_all() # 进程退出后重启 - threading.Thread(target=os.system, args=(f"{cmd} {executable} {' '.join(args)}",)).start() + threading.Thread(target=os.system, args=(f"{cmd} {executable} {' '.join(args)}",), daemon=True).start() sys.exit(0) self.call_restart_count += 1 @@ -161,8 +146,8 @@ class LiteyukiBot: """ 停止轻雪 """ + self.process_manager.terminate_all() self.stop_event.set() - self.loop.stop() def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC: """ diff --git a/liteyuki/bot/lifespan.py b/liteyuki/bot/lifespan.py index 06bcadad..e89b7910 100644 --- a/liteyuki/bot/lifespan.py +++ b/liteyuki/bot/lifespan.py @@ -130,12 +130,12 @@ class Lifespan: logger.debug("Running after_start functions") await self.run_funcs(self._after_start_funcs) - async def before_process_shutdown(self) -> None: + async def before_process_shutdown(self, *args, **kwargs) -> None: """ 停止前钩子 """ logger.debug("Running before_shutdown functions") - await self.run_funcs(self._before_process_shutdown_funcs) + await self.run_funcs(self._before_process_shutdown_funcs, *args, **kwargs) async def after_shutdown(self) -> None: """ @@ -144,12 +144,12 @@ class Lifespan: logger.debug("Running after_shutdown functions") await self.run_funcs(self._after_shutdown_funcs) - async def before_process_restart(self) -> None: + async def before_process_restart(self, *args, **kwargs) -> None: """ 重启前钩子 """ logger.debug("Running before_restart functions") - await self.run_funcs(self._before_process_restart_funcs) + await self.run_funcs(self._before_process_restart_funcs, *args, **kwargs) async def after_restart(self) -> None: """ diff --git a/liteyuki/core/manager.py b/liteyuki/core/manager.py index d8768471..3d76006c 100644 --- a/liteyuki/core/manager.py +++ b/liteyuki/core/manager.py @@ -10,6 +10,7 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved """ import asyncio import multiprocessing +import threading from multiprocessing import Process from typing import Any, Callable, TYPE_CHECKING, TypeAlias @@ -20,8 +21,8 @@ if TYPE_CHECKING: from liteyuki.bot.lifespan import Lifespan from liteyuki.comm.storage import KeyValueStore - from liteyuki.comm import Channel + if IS_MAIN_PROCESS: from liteyuki.comm.channel import get_channel, publish_channel, get_channels from liteyuki.comm.storage import shared_memory @@ -88,7 +89,7 @@ class ProcessManager: self.targets: dict[str, tuple[Callable, tuple, dict]] = {} self.processes: dict[str, Process] = {} - async def _run_process(self, name: str): + def _run_process(self, name: str): """ 开启后自动监控进程,并添加到进程字典中,会阻塞,请创建task Args: @@ -108,31 +109,31 @@ class ProcessManager: # 启动进程并监听信号 _start_process() - while True: - data = await chan_active.async_receive() + data = chan_active.receive() if data == 0: # 停止 logger.info(f"Stopping process {name}") - await self.lifespan.before_process_shutdown() self.terminate(name) break elif data == 1: # 重启 logger.info(f"Restarting process {name}") - await self.lifespan.before_process_shutdown() - await self.lifespan.before_process_restart() self.terminate(name) _start_process() continue else: logger.warning("Unknown data received, ignored.") - async def start_all(self): + def start_all(self): """ 对外启动方法,启动所有进程,创建asyncio task """ - [asyncio.create_task(self._run_process(name)) for name in self.targets] + # [asyncio.create_task(self._run_process(name)) for name in self.targets] + + for name in self.targets: + logger.debug(f"Starting process {name}") + threading.Thread(target=self._run_process, args=(name, ), daemon=True).start() def add_target(self, name: str, target: TARGET_FUNC, args: tuple = (), kwargs=None): """ diff --git a/src/liteyuki_plugins/lifespan_monitor.py b/src/liteyuki_plugins/lifespan_monitor.py index c2889448..68f3b814 100644 --- a/src/liteyuki_plugins/lifespan_monitor.py +++ b/src/liteyuki_plugins/lifespan_monitor.py @@ -28,16 +28,15 @@ def _(): @bot.on_before_process_shutdown -def _(): +def _(name="name"): logger.info("生命周期监控器:准备停止") @bot.on_before_process_restart -def _(): +def _(name="name"): logger.info("生命周期监控器:准备重启") @bot.on_after_start async def _(): - await asyncio.sleep(6) logger.info("生命周期监控器:启动完成") diff --git a/src/liteyuki_plugins/liteyukibot_plugin_nonebot/__init__.py b/src/liteyuki_plugins/liteyukibot_plugin_nonebot/__init__.py index 2aae4137..a0c6addd 100644 --- a/src/liteyuki_plugins/liteyukibot_plugin_nonebot/__init__.py +++ b/src/liteyuki_plugins/liteyukibot_plugin_nonebot/__init__.py @@ -13,6 +13,7 @@ import nonebot from liteyuki.utils import IS_MAIN_PROCESS from liteyuki.plugin import PluginMetadata, PluginType from .nb_utils import adapter_manager, driver_manager # type: ignore +from liteyuki.log import logger __plugin_meta__ = PluginMetadata( name="NoneBot2启动器", @@ -29,7 +30,6 @@ def nb_run(*args, **kwargs): Returns: """ # 给子进程传递通道对象 - kwargs.update(kwargs.get("nonebot", {})) # nonebot配置优先 nonebot.init(**kwargs) @@ -42,16 +42,12 @@ def nb_run(*args, **kwargs): nonebot.load_plugin("src.liteyuki_main") # 尝试加载轻雪主插件(Nonebot插件) except Exception as e: pass - nonebot.run() if IS_MAIN_PROCESS: + from liteyuki import get_bot from .dev_reloader import * liteyuki = get_bot() - - - @liteyuki.on_before_start - async def start_run_nonebot(): - liteyuki.process_manager.add_target(name="nonebot", target=nb_run, args=(), kwargs=liteyuki.config) + liteyuki.process_manager.add_target(name="nonebot", target=nb_run, args=(), kwargs=liteyuki.config) diff --git a/src/liteyuki_plugins/liteyukibot_plugin_nonebot/py.typed b/src/liteyuki_plugins/liteyukibot_plugin_nonebot/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/src/nonebot_plugins/to_liteyuki.py b/src/nonebot_plugins/to_liteyuki.py index 2541436a..706d62e1 100644 --- a/src/nonebot_plugins/to_liteyuki.py +++ b/src/nonebot_plugins/to_liteyuki.py @@ -28,28 +28,28 @@ __plugin_meta__ = PluginMetadata( recv_channel = Channel[LiteyukiMessageEvent](name="event_to_nonebot") -@on_message().handle() -async def _(bot: Bot, event: MessageEvent): - liteyuki_event = LiteyukiMessageEvent( - message_type=event.message_type, - message=event.dict()["message"], - raw_message=event.raw_message, - data=event.dict(), - bot_id=bot.self_id, - user_id=str(event.user_id), - session_id=str(event.user_id if event.message_type == "private" else event.group_id), - session_type=event.message_type, - receive_channel=recv_channel, - ) - shared_memory.publish("event_to_liteyuki", liteyuki_event) +# @on_message().handle() +# async def _(bot: Bot, event: MessageEvent): +# liteyuki_event = LiteyukiMessageEvent( +# message_type=event.message_type, +# message=event.dict()["message"], +# raw_message=event.raw_message, +# data=event.dict(), +# bot_id=bot.self_id, +# user_id=str(event.user_id), +# session_id=str(event.user_id if event.message_type == "private" else event.group_id), +# session_type=event.message_type, +# receive_channel=recv_channel, +# ) +# shared_memory.publish("event_to_liteyuki", liteyuki_event) -@get_driver().on_bot_connect -async def _(): - while True: - event = await recv_channel.async_receive() - bot: Bot = get_bot(event.bot_id) # type: ignore - if event.message_type == "private": - await bot.send_private_msg(user_id=int(event.session_id), message=event.data["message"]) - elif event.message_type == "group": - await bot.send_group_msg(group_id=int(event.session_id), message=event.data["message"]) +# @get_driver().on_bot_connect +# async def _(): +# while True: +# event = await recv_channel.async_receive() +# bot: Bot = get_bot(event.bot_id) # type: ignore +# if event.message_type == "private": +# await bot.send_private_msg(user_id=int(event.session_id), message=event.data["message"]) +# elif event.message_type == "group": +# await bot.send_group_msg(group_id=int(event.session_id), message=event.data["message"])