1
0
forked from bot/app

🐛 [plugin]: 暂时关闭轻雪推送功能

This commit is contained in:
远野千束 2024-09-01 13:22:12 +08:00
parent 736125f4ee
commit bdc32b26fe
7 changed files with 52 additions and 71 deletions

View File

@ -55,17 +55,11 @@ class LiteyukiBot:
"""加载插件加载器""" """加载插件加载器"""
load_plugin("liteyuki.plugins.plugin_loader") # 加载轻雪插件 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): async def _run(self):
""" """
启动逻辑 启动逻辑
""" """
await self.lifespan.before_start() # 启动前钩子 await self.lifespan.before_start() # 启动前钩子
await self.process_manager.start_all()
await self.lifespan.after_start() # 启动后钩子 await self.lifespan.after_start() # 启动后钩子
await self.keep_alive() await self.keep_alive()
@ -73,35 +67,26 @@ class LiteyukiBot:
""" """
外部启动接口 外部启动接口
""" """
self.process_manager.start_all()
try: try:
asyncio.run(self._run()) asyncio.run(self._run())
except KeyboardInterrupt: except KeyboardInterrupt:
logger.info("Liteyuki is stopping...") logger.opt(colors=True).info("<y>Liteyuki is stopping...</y>")
self.stop()
logger.opt(colors=True).info("<y>Liteyuki is stopped...</y>")
async def keep_alive(self): async def keep_alive(self):
""" """
保持轻雪运行 保持轻雪运行
""" """
logger.info("Liteyuki is keeping alive...")
try: try:
while not self.stop_event.is_set(): while not self.stop_event.is_set():
time.sleep(0.5) await asyncio.sleep(0.1)
except KeyboardInterrupt: except Exception:
logger.info("Liteyuki is stopping...") logger.info("Liteyuki is exiting...")
self.stop() 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): def restart(self, delay: int = 0):
""" """
重启轻雪本体 重启轻雪本体
@ -123,7 +108,7 @@ class LiteyukiBot:
cmd = "nohup" cmd = "nohup"
self.process_manager.terminate_all() 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) sys.exit(0)
self.call_restart_count += 1 self.call_restart_count += 1
@ -161,8 +146,8 @@ class LiteyukiBot:
""" """
停止轻雪 停止轻雪
""" """
self.process_manager.terminate_all()
self.stop_event.set() self.stop_event.set()
self.loop.stop()
def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC: def on_before_start(self, func: LIFESPAN_FUNC) -> LIFESPAN_FUNC:
""" """

View File

@ -130,12 +130,12 @@ class Lifespan:
logger.debug("Running after_start functions") logger.debug("Running after_start functions")
await self.run_funcs(self._after_start_funcs) 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") 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: async def after_shutdown(self) -> None:
""" """
@ -144,12 +144,12 @@ class Lifespan:
logger.debug("Running after_shutdown functions") logger.debug("Running after_shutdown functions")
await self.run_funcs(self._after_shutdown_funcs) 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") 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: async def after_restart(self) -> None:
""" """

View File

@ -10,6 +10,7 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
""" """
import asyncio import asyncio
import multiprocessing import multiprocessing
import threading
from multiprocessing import Process from multiprocessing import Process
from typing import Any, Callable, TYPE_CHECKING, TypeAlias from typing import Any, Callable, TYPE_CHECKING, TypeAlias
@ -20,8 +21,8 @@ if TYPE_CHECKING:
from liteyuki.bot.lifespan import Lifespan from liteyuki.bot.lifespan import Lifespan
from liteyuki.comm.storage import KeyValueStore from liteyuki.comm.storage import KeyValueStore
from liteyuki.comm import Channel from liteyuki.comm import Channel
if IS_MAIN_PROCESS: if IS_MAIN_PROCESS:
from liteyuki.comm.channel import get_channel, publish_channel, get_channels from liteyuki.comm.channel import get_channel, publish_channel, get_channels
from liteyuki.comm.storage import shared_memory from liteyuki.comm.storage import shared_memory
@ -88,7 +89,7 @@ class ProcessManager:
self.targets: dict[str, tuple[Callable, tuple, dict]] = {} self.targets: dict[str, tuple[Callable, tuple, dict]] = {}
self.processes: dict[str, Process] = {} self.processes: dict[str, Process] = {}
async def _run_process(self, name: str): def _run_process(self, name: str):
""" """
开启后自动监控进程并添加到进程字典中会阻塞请创建task 开启后自动监控进程并添加到进程字典中会阻塞请创建task
Args: Args:
@ -108,31 +109,31 @@ class ProcessManager:
# 启动进程并监听信号 # 启动进程并监听信号
_start_process() _start_process()
while True: while True:
data = await chan_active.async_receive() data = chan_active.receive()
if data == 0: if data == 0:
# 停止 # 停止
logger.info(f"Stopping process {name}") logger.info(f"Stopping process {name}")
await self.lifespan.before_process_shutdown()
self.terminate(name) self.terminate(name)
break break
elif data == 1: elif data == 1:
# 重启 # 重启
logger.info(f"Restarting process {name}") logger.info(f"Restarting process {name}")
await self.lifespan.before_process_shutdown()
await self.lifespan.before_process_restart()
self.terminate(name) self.terminate(name)
_start_process() _start_process()
continue continue
else: else:
logger.warning("Unknown data received, ignored.") logger.warning("Unknown data received, ignored.")
async def start_all(self): def start_all(self):
""" """
对外启动方法启动所有进程创建asyncio task 对外启动方法启动所有进程创建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): def add_target(self, name: str, target: TARGET_FUNC, args: tuple = (), kwargs=None):
""" """

View File

@ -28,16 +28,15 @@ def _():
@bot.on_before_process_shutdown @bot.on_before_process_shutdown
def _(): def _(name="name"):
logger.info("生命周期监控器:准备停止") logger.info("生命周期监控器:准备停止")
@bot.on_before_process_restart @bot.on_before_process_restart
def _(): def _(name="name"):
logger.info("生命周期监控器:准备重启") logger.info("生命周期监控器:准备重启")
@bot.on_after_start @bot.on_after_start
async def _(): async def _():
await asyncio.sleep(6)
logger.info("生命周期监控器:启动完成") logger.info("生命周期监控器:启动完成")

View File

@ -13,6 +13,7 @@ import nonebot
from liteyuki.utils import IS_MAIN_PROCESS from liteyuki.utils import IS_MAIN_PROCESS
from liteyuki.plugin import PluginMetadata, PluginType from liteyuki.plugin import PluginMetadata, PluginType
from .nb_utils import adapter_manager, driver_manager # type: ignore from .nb_utils import adapter_manager, driver_manager # type: ignore
from liteyuki.log import logger
__plugin_meta__ = PluginMetadata( __plugin_meta__ = PluginMetadata(
name="NoneBot2启动器", name="NoneBot2启动器",
@ -29,7 +30,6 @@ def nb_run(*args, **kwargs):
Returns: Returns:
""" """
# 给子进程传递通道对象 # 给子进程传递通道对象
kwargs.update(kwargs.get("nonebot", {})) # nonebot配置优先 kwargs.update(kwargs.get("nonebot", {})) # nonebot配置优先
nonebot.init(**kwargs) nonebot.init(**kwargs)
@ -42,16 +42,12 @@ def nb_run(*args, **kwargs):
nonebot.load_plugin("src.liteyuki_main") # 尝试加载轻雪主插件Nonebot插件 nonebot.load_plugin("src.liteyuki_main") # 尝试加载轻雪主插件Nonebot插件
except Exception as e: except Exception as e:
pass pass
nonebot.run() nonebot.run()
if IS_MAIN_PROCESS: if IS_MAIN_PROCESS:
from liteyuki import get_bot
from .dev_reloader import * from .dev_reloader import *
liteyuki = get_bot() 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)

View File

@ -28,28 +28,28 @@ __plugin_meta__ = PluginMetadata(
recv_channel = Channel[LiteyukiMessageEvent](name="event_to_nonebot") recv_channel = Channel[LiteyukiMessageEvent](name="event_to_nonebot")
@on_message().handle() # @on_message().handle()
async def _(bot: Bot, event: MessageEvent): # async def _(bot: Bot, event: MessageEvent):
liteyuki_event = LiteyukiMessageEvent( # liteyuki_event = LiteyukiMessageEvent(
message_type=event.message_type, # message_type=event.message_type,
message=event.dict()["message"], # message=event.dict()["message"],
raw_message=event.raw_message, # raw_message=event.raw_message,
data=event.dict(), # data=event.dict(),
bot_id=bot.self_id, # bot_id=bot.self_id,
user_id=str(event.user_id), # user_id=str(event.user_id),
session_id=str(event.user_id if event.message_type == "private" else event.group_id), # session_id=str(event.user_id if event.message_type == "private" else event.group_id),
session_type=event.message_type, # session_type=event.message_type,
receive_channel=recv_channel, # receive_channel=recv_channel,
) # )
shared_memory.publish("event_to_liteyuki", liteyuki_event) # shared_memory.publish("event_to_liteyuki", liteyuki_event)
@get_driver().on_bot_connect # @get_driver().on_bot_connect
async def _(): # async def _():
while True: # while True:
event = await recv_channel.async_receive() # event = await recv_channel.async_receive()
bot: Bot = get_bot(event.bot_id) # type: ignore # bot: Bot = get_bot(event.bot_id) # type: ignore
if event.message_type == "private": # if event.message_type == "private":
await bot.send_private_msg(user_id=int(event.session_id), message=event.data["message"]) # await bot.send_private_msg(user_id=int(event.session_id), message=event.data["message"])
elif event.message_type == "group": # elif event.message_type == "group":
await bot.send_group_msg(group_id=int(event.session_id), message=event.data["message"]) # await bot.send_group_msg(group_id=int(event.session_id), message=event.data["message"])