mirror of https://github.com/Mai-with-u/MaiBot.git
Compare commits
6 Commits
2f4d049340
...
5848cd60f9
| Author | SHA1 | Date |
|---|---|---|
|
|
5848cd60f9 | |
|
|
3ab0a2c737 | |
|
|
52ce7e403b | |
|
|
eae11e218e | |
|
|
a867b44867 | |
|
|
5b38423a89 |
58
bot.py
58
bot.py
|
|
@ -56,6 +56,7 @@ def run_runner_process():
|
|||
# 设置环境变量,标记子进程为 Worker 进程
|
||||
env = os.environ.copy()
|
||||
env["MAIBOT_WORKER_PROCESS"] = "1"
|
||||
env["MAIBOT_RUNNER_PID"] = str(os.getpid()) # 传递 Runner PID 供 Worker 监控
|
||||
|
||||
while True:
|
||||
logger.info(f"正在启动 {script_file}...")
|
||||
|
|
@ -175,6 +176,60 @@ def easter_egg():
|
|||
print(rainbow_text)
|
||||
|
||||
|
||||
def _start_parent_monitor():
|
||||
"""启动父进程存活监控守护线程,检测到 Runner 终止后触发优雅退出"""
|
||||
import ctypes
|
||||
import signal
|
||||
import threading
|
||||
|
||||
try:
|
||||
runner_pid = int(os.environ.get("MAIBOT_RUNNER_PID", "0"))
|
||||
except (ValueError, TypeError):
|
||||
return
|
||||
if not runner_pid:
|
||||
return
|
||||
|
||||
def is_alive_unix(pid):
|
||||
return os.getppid() == pid
|
||||
|
||||
def trigger_exit():
|
||||
# Logger 容错:解释器关闭阶段 Logger 可能已被销毁
|
||||
try:
|
||||
get_logger("main").warning("检测到 Runner 进程已终止,正在触发优雅退出...")
|
||||
except Exception:
|
||||
print("[ParentMonitor] 检测到 Runner 进程已终止,正在触发优雅退出...")
|
||||
signal.raise_signal(signal.SIGINT) # 触发 KeyboardInterrupt,走正常关闭流程
|
||||
|
||||
def monitor():
|
||||
if platform.system() == "Windows":
|
||||
# Windows: 循环外获取句柄,循环内只检查退出码,减少系统调用
|
||||
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
|
||||
STILL_ACTIVE = 259
|
||||
kernel32 = ctypes.windll.kernel32
|
||||
handle = kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, runner_pid)
|
||||
if not handle:
|
||||
# 进程已不存在或无权限访问,直接触发退出
|
||||
return trigger_exit()
|
||||
try:
|
||||
exit_code = ctypes.c_ulong()
|
||||
while True:
|
||||
if not kernel32.GetExitCodeProcess(handle, ctypes.byref(exit_code)):
|
||||
break # API 调用失败,假定进程已退出
|
||||
if exit_code.value != STILL_ACTIVE:
|
||||
break # 进程已退出
|
||||
time.sleep(2)
|
||||
finally:
|
||||
kernel32.CloseHandle(handle)
|
||||
else:
|
||||
# Unix: 检测 ppid 是否变化
|
||||
while is_alive_unix(runner_pid):
|
||||
time.sleep(2)
|
||||
|
||||
trigger_exit()
|
||||
|
||||
threading.Thread(target=monitor, daemon=True, name="ParentMonitor").start()
|
||||
|
||||
|
||||
async def graceful_shutdown(): # sourcery skip: use-named-expression
|
||||
try:
|
||||
logger.info("正在优雅关闭麦麦...")
|
||||
|
|
@ -322,6 +377,9 @@ def raw_main():
|
|||
if __name__ == "__main__":
|
||||
exit_code = 0 # 用于记录程序最终的退出状态
|
||||
try:
|
||||
# 启动父进程存活监控(Runner 异常退出时自动触发优雅关闭)
|
||||
_start_parent_monitor()
|
||||
|
||||
# 获取MainSystem实例
|
||||
main_system = raw_main()
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -11,21 +11,21 @@
|
|||
<link rel="icon" type="image/x-icon" href="/maimai.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>MaiBot Dashboard</title>
|
||||
<script type="module" crossorigin src="/assets/index-HQ4xq01Z.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DD4VGX3W.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/react-vendor-BmxF9s7Q.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/router-9vIXuQkh.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/utils-BqoaXoQ1.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/radix-core-DyJi0yyw.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/radix-extra-DmmnfeQE.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/charts-simvewUa.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/icons-CBTr14-W.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/icons-8bdCaZgy.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/codemirror-TZqPU532.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/dnd-BiPfFtVp.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/misc-CJqnlRwD.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/reactflow-DtsZHOR4.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/uppy-DFP_VzYR.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/markdown-CKA5gBQ9.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-ByrlkbsK.css">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-RB5cYCSR.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" class="notranslate"></div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue