From d494093850dd37dee0b66017a1cabd3e8ec12218 Mon Sep 17 00:00:00 2001 From: Snowflake Date: Mon, 8 Jun 2026 20:21:47 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=A8=E9=9D=A2=E4=BF=AE=E5=A4=8D5?= =?UTF-8?q?=E4=B8=AA=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APP_VERSIONS_LIST | 3 ++- src/main.rb | 27 +++++++++++++++------------ src/method_executor.rb | 14 ++++++++++---- src/systemd_notifier.rb | 1 + src/updates.rb | 4 ++-- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/APP_VERSIONS_LIST b/APP_VERSIONS_LIST index f6df67e..b2e0a25 100644 --- a/APP_VERSIONS_LIST +++ b/APP_VERSIONS_LIST @@ -3,4 +3,5 @@ b43527c 8cd942b 83acd30 b2baee0 -13c4c19 \ No newline at end of file +13c4c19 +5668d65 \ No newline at end of file diff --git a/src/main.rb b/src/main.rb index 10a366f..4440c0b 100644 --- a/src/main.rb +++ b/src/main.rb @@ -78,29 +78,32 @@ def main_once (0...TRY_TIMES).each do chkrslt = ServerStatusDetector::MinecraftServer.self_diag chkrslts.append(chkrslt) + sleep 0.5 unless chkrslt[:type] # 只在失败时等待后再重试 end if chkrslts.all? { |chkrslt_in| chkrslt_in[:type] } MethodExecutor.record('debug', 'mainloop', 'Server health check passed.') + MethodExecutor.reset_rst_counter else chkrslts.each do |result| MethodExecutor.record('warn', 'mainloop', "Server health check FAILED: #{result[:message]}") end MethodExecutor.record('info', 'mainloop', "Checked #{TRY_TIMES} time.") - if chkrslts.any? { |chkrslt_in| chkrslt_in[:operation].include?('Record') } + if chkrslts.any? { |chkrslt_in| (chkrslt_in[:operation] || []).include?('Record') } MethodExecutor.record('warn', 'mainloop', 'Action: Record -> Server died!') - if chkrslts.any? { |chkrslt_in| chkrslt_in[:message] == 'Server died for unknown reason, and will be restarted.' } + if chkrslts.any? { |chkrslt_in| (chkrslt_in[:operation] || []).include?('ForceResetServerProcess') } MethodExecutor.record('info', 'mainloop', 'Action: ForceResetServerProcess triggered.') - MethodExecutor.reset_minecraft_server - # 重启后等待服务器启动(MC服务器启动通常需要30秒~2分钟) - cooldown_beg = Time.now - MethodExecutor.record('info', 'mainloop', "Cooling down #{RST_COOLDOWN_DURATION}s for server startup...") - # rubocop:disable Metrics/BlockNesting - while Time.now < cooldown_beg + RST_COOLDOWN_DURATION - sleep 1 - SystemdNotifier.notify('WATCHDOG=1') + if MethodExecutor.reset_minecraft_server + # 重启后等待服务器启动(MC服务器启动通常需要30秒~2分钟) + cooldown_beg = Time.now + MethodExecutor.record('info', 'mainloop', "Cooling down #{RST_COOLDOWN_DURATION}s for server startup...") + # rubocop:disable Metrics/BlockNesting + while Time.now < cooldown_beg + RST_COOLDOWN_DURATION + sleep 1 + SystemdNotifier.notify('WATCHDOG=1') + end + # rubocop:enable Metrics/BlockNesting + MethodExecutor.record('info', 'mainloop', 'Cooldown finished, resuming monitoring.') end - # rubocop:enable Metrics/BlockNesting - MethodExecutor.record('info', 'mainloop', 'Cooldown finished, resuming monitoring.') end end end diff --git a/src/method_executor.rb b/src/method_executor.rb index 733eab2..df07441 100644 --- a/src/method_executor.rb +++ b/src/method_executor.rb @@ -66,13 +66,13 @@ class MethodExecutor # rubocop:enable Metrics/MethodLength # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity - # @return [void] + # @return [Boolean] true if a restart was attempted, false if recovered from idle def self.reset_minecraft_server record('info', 'reset', "Attempt ##{@@rst_counter + 1} to reset Minecraft server.") if @@rst_counter >= RST_COUNTS_LIMIT record('error', 'reset', - "Tried #{RST_COUNTS_LIMIT} times and failed, now I'll idle until server is manually restarted.") + "Tried #{RST_COUNTS_LIMIT} times and failed, now I'll idle until server is manually recovered.") loop do sleep 10 SystemdNotifier.notify('WATCHDOG=1') if defined?(SystemdNotifier) @@ -80,7 +80,7 @@ class MethodExecutor record('info', 'reset', 'Server recovered! Resuming normal monitoring.') @@rst_counter = 0 - return + return false end end @@ -106,7 +106,6 @@ class MethodExecutor elapsed = (Time.now - tick_beg).round(2) if status.success? record('info', 'reset', "'systemctl restart' succeeded in #{elapsed}s.") - @@rst_counter = 0 # 成功时重置计数器 else record('error', 'reset', "'systemctl restart' failed with exitcode #{status.exitstatus} after #{elapsed}s.") @@ -128,6 +127,13 @@ class MethodExecutor end # rubocop:enable Metrics/BlockLength end + true + end + + # Resets the restart counter when server health check passes. + # @return [void] + def self.reset_rst_counter + @@rst_counter = 0 end # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity # rubocop:enable Style/ClassVars diff --git a/src/systemd_notifier.rb b/src/systemd_notifier.rb index caaa8a4..9390727 100644 --- a/src/systemd_notifier.rb +++ b/src/systemd_notifier.rb @@ -17,6 +17,7 @@ # Sends keep-alive notifications (including WATCHDOG=1) to systemd # via the NOTIFY_SOCKET datagram socket, enabling service supervision. class SystemdNotifier + require 'socket' require_relative 'method_executor' diff --git a/src/updates.rb b/src/updates.rb index 38d8901..2fd5be3 100644 --- a/src/updates.rb +++ b/src/updates.rb @@ -18,11 +18,11 @@ require 'net/http' require 'uri' # @type const RELEASE_SERIAL_CODE: String -RELEASE_SERIAL_CODE = '13c4c19git ' +RELEASE_SERIAL_CODE = '5668d65' # @type const CHANNEL: String CHANNEL = 'dev' # @type const VERSION_LIST_URL: String -VERSION_LIST_URL = "https://gitee.com/api/v5/repos/SCU_team/mine-sentinel/contents/APP_VERSIONS_LIST?ref=#{CHANNEL}" +VERSION_LIST_URL = "https://gitee.com/SCU_team/mine-sentinel/raw/#{CHANNEL}/APP_VERSIONS_LIST" # @type const RECURSIVE_RETRY_DEPTH: Integer RECURSIVE_RETRY_DEPTH = 3