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 秒
+53 -47
View File
@@ -12,74 +12,70 @@
# 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 puts ' ___ __ ___ ___ ___ '
# 原有代码 puts ' |\/| | |\ | |__ /__` |__ |\ | | | |\ | |__ | '
rescue => e puts ' | | | | \| |___ .__/ |___ | \| | | | \| |___ |___ '
# 强制输出到stderr puts " MineSentinel dev-rolling version by <*> S.A. [@SNOWARE] and owned by SCU team."
$stderr.puts "[CRITICAL] Unhandled exception: #{e.message}" puts " Copyleft (c) 2026 S.A. SNOWARE-SCU. This program is licensed under Mulan PubL v2."
$stderr.puts e.backtrace.join("\n") puts " E-mail: SALflake@qq.com | QQ: 758522192 | Website: https://swe-iss.rth1.xyz/softwares/minesentinel."
exit 1 puts
end
puts ' ___ __ ___ ___ ___ ' require_relative 'method_executor' # 日志系统在此时初始化
puts ' |\/| | |\ | |__ /__` |__ |\ | | | |\ | |__ | ' MethodExecutor.record("debug", "init", "Initialized MethodExecutor, which implements logging system and intervening functions.")
puts ' | | | | \| |___ .__/ |___ | \| | | | \| |___ |___ ' require_relative 'server_status_detector'
puts " MineSentinel dev-rolling version by <*> S.A. [@SNOWARE] and owned by SCU team." require_relative 'systemd_notifier' # 心跳系统在此时初始化
puts " Copyleft (c) 2026 S.A. SNOWARE-SCU. This program is licensed under Mulan PubL v2." require_relative 'config'
puts " E-mail: SALflake@qq.com | QQ: 758522192 | Website: https://https://swe-iss.rth1.xyz/softwares/minesentinel." MethodExecutor.record("debug", "init", "Initialized SystemdNotifier, which implements systemd watchdog feeder.")
puts
require_relative 'method_executor' # 日志系统在此时初始化 # 确认是否具有展开干预操作的权限 如果因场景不同不需要请注释这部分内容
MethodExecutor.record("debug", "init", "Initialized MethodExecutor, which implements logging system and intervening functions.") unless Process.euid == 0
require_relative 'server_status_detector'
require_relative 'systemd_notifier' # 心跳系统在此时初始化
MethodExecutor.record("debug", "init", "Initialized SystemdNotifier, which implements systemd watchdog feeder.")
# 确认是否具有展开干预操作的权限 如果因场景不同不需要请注释这部分内容
unless Process.euid == 0
MethodExecutor.record("error", "init", "Permission denied: root required to intervene Systemd Services.") MethodExecutor.record("error", "init", "Permission denied: root required to intervene Systemd Services.")
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=), MethodExecutor.record("info", "mainloop",
# 等待服务器端口就绪,避免误判为崩溃
INITIAL_GRACE = 300 # 初次启动等待 300 秒
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
while Time.now < grace_deadline while Time.now < grace_deadline
sleep 5 sleep 5
if ServerStatusDetector::MinecraftServer.self_diag[:type] if ServerStatusDetector::MinecraftServer.self_diag[:type]
MethodExecutor.record("info", "mainloop", MethodExecutor.record("info", "mainloop",
"Server port is open during grace period, resuming normal monitoring.") "Server port is open during grace period, resuming normal monitoring.")
break break
end end
end
MethodExecutor.record("info", "mainloop", "Grace period ended.")
main_loop
end end
MethodExecutor.record("info", "mainloop", "Grace period ended.")
# 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)