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"])