fix: 修复systemd socket协议、格式化代码、拆分配置常量

This commit is contained in:
2026-06-08 10:30:38 +08:00
parent c99188ef78
commit 3f7ebfb52e
4 changed files with 106 additions and 99 deletions
+3
View File
@@ -0,0 +1,3 @@
INITIAL_GRACE = 300 # 初次启动等待 300 秒
TRY_TIMES = 3 # 尝试次数
RST_COOLDOWN_DURATION = 200 # 重启冷却期 200 秒
+31 -25
View File
@@ -12,28 +12,20 @@
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. # MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PubL v2 for more details. # See the Mulan PubL v2 for more details.
# main.rb 顶部添加 def main
begin
# 原有代码
rescue => e
# 强制输出到stderr
$stderr.puts "[CRITICAL] Unhandled exception: #{e.message}"
$stderr.puts e.backtrace.join("\n")
exit 1
end
puts ' ___ __ ___ ___ ___ ' puts ' ___ __ ___ ___ ___ '
puts ' |\/| | |\ | |__ /__` |__ |\ | | | |\ | |__ | ' puts ' |\/| | |\ | |__ /__` |__ |\ | | | |\ | |__ | '
puts ' | | | | \| |___ .__/ |___ | \| | | | \| |___ |___ ' puts ' | | | | \| |___ .__/ |___ | \| | | | \| |___ |___ '
puts " MineSentinel dev-rolling version by <*> S.A. [@SNOWARE] and owned by SCU team." puts " MineSentinel dev-rolling version by <*> S.A. [@SNOWARE] and owned by SCU team."
puts " Copyleft (c) 2026 S.A. SNOWARE-SCU. This program is licensed under Mulan PubL v2." puts " Copyleft (c) 2026 S.A. SNOWARE-SCU. This program is licensed under Mulan PubL v2."
puts " E-mail: SALflake@qq.com | QQ: 758522192 | Website: https://https://swe-iss.rth1.xyz/softwares/minesentinel." puts " E-mail: SALflake@qq.com | QQ: 758522192 | Website: https://swe-iss.rth1.xyz/softwares/minesentinel."
puts puts
require_relative 'method_executor' # 日志系统在此时初始化 require_relative 'method_executor' # 日志系统在此时初始化
MethodExecutor.record("debug", "init", "Initialized MethodExecutor, which implements logging system and intervening functions.") MethodExecutor.record("debug", "init", "Initialized MethodExecutor, which implements logging system and intervening functions.")
require_relative 'server_status_detector' require_relative 'server_status_detector'
require_relative 'systemd_notifier' # 心跳系统在此时初始化 require_relative 'systemd_notifier' # 心跳系统在此时初始化
require_relative 'config'
MethodExecutor.record("debug", "init", "Initialized SystemdNotifier, which implements systemd watchdog feeder.") MethodExecutor.record("debug", "init", "Initialized SystemdNotifier, which implements systemd watchdog feeder.")
# 确认是否具有展开干预操作的权限 如果因场景不同不需要请注释这部分内容 # 确认是否具有展开干预操作的权限 如果因场景不同不需要请注释这部分内容
@@ -42,12 +34,10 @@ unless Process.euid == 0
raise Errno::EPERM raise Errno::EPERM
end end
MethodExecutor.record("info", "mainloop", "MineSentinel started, entering mainloop.") MethodExecutor.record("info", "mainloop", "MineSentinel started, entering mainloop.")
# 初次启动:MineSentinel 先于 minecraft 启动(systemd Before=), # 初次启动:MineSentinel 先于 minecraft 启动(systemd Before=),
# 等待服务器端口就绪,避免误判为崩溃 # 等待服务器端口就绪,避免误判为崩溃
INITIAL_GRACE = 300 # 初次启动等待 300 秒
MethodExecutor.record("info", "mainloop", MethodExecutor.record("info", "mainloop",
"Initial startup grace period #{INITIAL_GRACE}s — waiting for server to come up...") "Initial startup grace period #{INITIAL_GRACE}s — waiting for server to come up...")
grace_deadline = Time.now + INITIAL_GRACE grace_deadline = Time.now + INITIAL_GRACE
@@ -60,26 +50,32 @@ while Time.now < grace_deadline
end end
end end
MethodExecutor.record("info", "mainloop", "Grace period ended.") MethodExecutor.record("info", "mainloop", "Grace period ended.")
main_loop
end
# Functional mainloop. # Functional mainloop.
def main def main_once
chkrslts = []
for i in 0..TRY_TIMES
chkrslt = ServerStatusDetector::MinecraftServer.self_diag chkrslt = ServerStatusDetector::MinecraftServer.self_diag
if chkrslt[:type] chkrslts.append(chkrslt)
end
if chkrslts.all? { |chkrslt_in| chkrslt_in[:type] }
MethodExecutor.record("debug", "mainloop", "Server health check passed.") MethodExecutor.record("debug", "mainloop", "Server health check passed.")
else else
MethodExecutor.record("warn", "mainloop", "Server health check FAILED: #{chkrslt[:message]}") for chkrslt_in in chkrslts
for operation in chkrslt[:operation] MethodExecutor.record("warn", "mainloop", "Server health check FAILED: #{chkrslt_in[:message]}")
if operation == "Record" end
# 消息已在 self_diag 中生成,这里仅记录操作 MethodExecutor.record("info", "mainloop", "Checked #{TRY_TIMES} time.")
if chkrslts.any? { |chkrslt_in| chkrslt_in[:operation] == "Record" }
MethodExecutor.record("warn", "mainloop", "Action: Record -> Server died!") MethodExecutor.record("warn", "mainloop", "Action: Record -> Server died!")
elsif operation == "ForceResetServerProcess" if chkrslts.any? { |chkrslt_in| chkrslt_in[:message] == "Server died for unknown reason, and will be restarted." }
MethodExecutor.record("info", "mainloop", "Action: ForceResetServerProcess triggered.") MethodExecutor.record("info", "mainloop", "Action: ForceResetServerProcess triggered.")
MethodExecutor.reset_minecraft_server MethodExecutor.reset_minecraft_server
# 重启后等待服务器启动(MC服务器启动通常需要30秒~2分钟) # 重启后等待服务器启动(MC服务器启动通常需要30秒~2分钟)
cooldown_duration = 200 # 200秒冷却期
cooldown_beg = Time.now cooldown_beg = Time.now
MethodExecutor.record("info", "mainloop", "Cooling down #{cooldown}s for server startup...") MethodExecutor.record("info", "mainloop", "Cooling down #{RST_COOLDOWN_DURATION}s for server startup...")
while Time.now < cooldown_beg + cooldown_duration while Time.now < cooldown_beg + RST_COOLDOWN_DURATION
sleep 1 sleep 1
SystemdNotifier.notify("WATCHDOG=1") SystemdNotifier.notify("WATCHDOG=1")
end end
@@ -89,9 +85,19 @@ def main
end end
end end
def main_loop
while true while true
sleep 1.5 sleep 1.5
SystemdNotifier.notify("WATCHDOG=1") SystemdNotifier.notify("WATCHDOG=1")
main main_once
end
end
begin
main
rescue => e
# 强制输出到stderr
$stderr.puts "[CRITICAL] Unhandled exception: #{e.message}"
$stderr.puts e.backtrace.join("\n")
exit 1
end end
-2
View File
@@ -89,7 +89,6 @@ class MethodExecutor
while true while true
sleep 0.5 sleep 0.5
begin
SystemdNotifier.notify("WATCHDOG=1") SystemdNotifier.notify("WATCHDOG=1")
proc_status = Process.waitpid2(pid, Process::WNOHANG) proc_status = Process.waitpid2(pid, Process::WNOHANG)
if proc_status # 子进程已退出,返回 [pid, status] if proc_status # 子进程已退出,返回 [pid, status]
@@ -118,7 +117,6 @@ class MethodExecutor
end end
end end
end end
end
end end
+1 -1
View File
@@ -55,7 +55,7 @@ module ServerStatusDetector
class MinecraftServer < TcpServer # 继承为TcpServer编写的属性和方法 class MinecraftServer < TcpServer # 继承为TcpServer编写的属性和方法
def self.self_diag() def self_diag
res = test_port('127.0.0.1', 25565) res = test_port('127.0.0.1', 25565)