From c61ffe2f75ae0822c8fdb53d18b6142a55e90dc4 Mon Sep 17 00:00:00 2001 From: Snowflake Date: Mon, 8 Jun 2026 07:30:21 +0800 Subject: [PATCH] Fix systemd misjudging by sending heartbeats. --- main.rb | 10 ++++++++-- method_executor.rb | 3 ++- systemd_notifier.rb | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 systemd_notifier.rb diff --git a/main.rb b/main.rb index 8133f81..f48dbf6 100644 --- a/main.rb +++ b/main.rb @@ -24,6 +24,7 @@ end require_relative 'method_executor' # 日志系统在此时初始化 require_relative 'server_status_detector' +require_relative 'systemd_notifier' # 心跳系统在此时初始化 MethodExecutor.record("info", "mainloop", "MineSentinel started, entering mainloop.") @@ -58,9 +59,13 @@ def main MethodExecutor.record("info", "mainloop", "Action: ForceResetServerProcess triggered.") MethodExecutor.reset_minecraft_server # 重启后等待服务器启动(MC服务器启动通常需要30秒~2分钟) - cooldown = 200 # 200秒冷却期 + cooldown_duration = 200 # 200秒冷却期 + cooldown_beg = Time.now MethodExecutor.record("info", "mainloop", "Cooling down #{cooldown}s for server startup...") - sleep cooldown + while Time.now < cooldown_beg + cooldown_duration + sleep 1 + SystemdNotifier.notify("WATCHDOG=1") + end MethodExecutor.record("info", "mainloop", "Cooldown finished, resuming monitoring.") end end @@ -70,5 +75,6 @@ end while true sleep 1.5 + SystemdNotifier.notify("WATCHDOG=1") main end diff --git a/method_executor.rb b/method_executor.rb index d1603b1..b800683 100644 --- a/method_executor.rb +++ b/method_executor.rb @@ -121,4 +121,5 @@ class MethodExecutor end - end + +end diff --git a/systemd_notifier.rb b/systemd_notifier.rb new file mode 100644 index 0000000..cc4e9ff --- /dev/null +++ b/systemd_notifier.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class SystemdNotifier + require_relative 'method_executor' + public + + @notify_socket = ENV["NOTIFY_SOCKET"] + @watchdog_usec = (ENV["WATCHDOG_USEC"] || '0').to_i + + unless @notify_socket && File.socket?(@notify_socket) + MethodExecutor.record("error", "heartbeat", "NOTIFY_SOCKET is not set or is not a socket, am I a service?") + @enable_heartbeat = false + else + @enable_heartbeat = true + @socket = UNIXSocket.new(@notify_socket) + end + + def enabled? + @enable_heartbeat + end + + def notify_heartbeat(message) + return unless @enable_heartbeat + + begin + @socket.send(message, 0) + rescue => e + MethodExecutor.error("heartbeat", "Failed to send heartbeat: #{e}") + @enable_heartbeat = false + end + end + + def self.notify(message) + MethodExecutor.record("info", "systemd", message) + end +end