release: 发布版本 60176fa,RuboCop 零告警,网页新增版本号展示

This commit is contained in:
2026-06-08 11:47:00 +08:00
parent 60176fa316
commit 8cd942be2d
9 changed files with 171 additions and 140 deletions
+59 -55
View File
@@ -18,30 +18,31 @@ PERSISTENCE_PERIOD = 30 # Wait for systemctl to take the order.
require 'logger'
require_relative 'server_status_detector'
# rubocop:disable Style/ClassVars
class MethodExecutor
public
RST_COUNTS_LIMIT = 10
@@rst_counter = 0
# Initialize the standard log system.
@@logger = Logger.new(STDOUT) # This script will be launched as a systemd server.
STDOUT.sync = true
STDERR.sync = true
@@logger = Logger.new($stdout) # This script will be launched as a systemd server.
$stdout.sync = true
$stderr.sync = true
# Fetch the environmental variable and convert it into log level.
@@logger.level = case ENV["LOG_LEVEL"] # @为单个实例(半生不熟的概念,貌似是在不同的空间独立创建),@@为共享同一个
when nil # Default config.
Logger::Severity::DEBUG
when "debug"
Logger::Severity::DEBUG
when "info"
Logger::Severity::INFO
when "warn"
Logger::Severity::WARN
when "error"
Logger::Severity::ERROR
else
raise ArgumentError
@@logger.level = case ENV.fetch('LOG_LEVEL', nil) # @为单个实例(半生不熟的概念,貌似是在不同的空间独立创建),@@为共享同一个
when nil, 'debug' # Default config.
Logger::Severity::DEBUG
when 'info'
Logger::Severity::INFO
when 'warn'
Logger::Severity::WARN
when 'error'
Logger::Severity::ERROR
else
raise ArgumentError
end
@@logger.progname = "MineSentinel"
@@logger.progname = 'MineSentinel'
# rubocop:disable Metrics/MethodLength
# @param level [String] "info" | "warn" | "error" | "debug"
# @param module_name [String]
@@ -49,82 +50,85 @@ class MethodExecutor
# @return [void]
def self.record(level, module_name, message)
case level
when "info"
when 'info'
@@logger.info("#{module_name}: #{message}")
when "warn"
when 'warn'
@@logger.warn("#{module_name}: #{message}")
when "error"
when 'error'
@@logger.error("#{module_name}: #{message}")
when "debug"
when 'debug'
@@logger.debug("#{module_name}: #{message}")
else
raise ArgumentError
end
end
# rubocop:enable Metrics/MethodLength
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# @return [void]
def self.reset_minecraft_server
self.record("info", "reset", "Attempt ##{@@rst_counter + 1} to reset Minecraft server.")
record('info', 'reset', "Attempt ##{@@rst_counter + 1} to reset Minecraft server.")
if @@rst_counter >= RST_COUNTS_LIMIT
self.record("error", "reset",
"Tried #{RST_COUNTS_LIMIT} times and failed, now I'll idle until server is manually restarted.")
while true
record('error', 'reset',
"Tried #{RST_COUNTS_LIMIT} times and failed, now I'll idle until server is manually restarted.")
loop do
sleep 10
SystemdNotifier.notify("WATCHDOG=1") if defined?(SystemdNotifier)
if ServerStatusDetector::MinecraftServer.self_diag[:type] == true
self.record("info", "reset", "Server recovered! Resuming normal monitoring.")
@@rst_counter = 0
return
end
SystemdNotifier.notify('WATCHDOG=1') if defined?(SystemdNotifier)
next unless ServerStatusDetector::MinecraftServer.self_diag[:type] == true
record('info', 'reset', 'Server recovered! Resuming normal monitoring.')
@@rst_counter = 0
return
end
end
@@rst_counter += 1
unless Process.euid == 0
self.record("error", "reset", "Permission denied: root required to manage systemd services.")
unless Process.euid.zero?
record('error', 'reset', 'Permission denied: root required to manage systemd services.')
raise Errno::EPERM
end
self.record("info", "reset", "Spawning 'systemctl restart minecraft' (PID will be captured)...")
pid = spawn "systemctl restart minecraft"
self.record("debug", "reset", "systemctl restart spawned with PID #{pid}.")
record('info', 'reset', "Spawning 'systemctl restart minecraft' (PID will be captured)...")
pid = spawn 'systemctl restart minecraft'
record('debug', 'reset', "systemctl restart spawned with PID #{pid}.")
tick_beg = Time.now
while true
# rubocop:disable Metrics/BlockLength
loop do
sleep 0.5
SystemdNotifier.notify("WATCHDOG=1")
SystemdNotifier.notify('WATCHDOG=1')
proc_status = Process.waitpid2(pid, Process::WNOHANG)
if proc_status # 子进程已退出,返回 [pid, status]
_, status = proc_status
elapsed = (Time.now - tick_beg).round(2)
if status.success?
self.record("info", "reset", "'systemctl restart' succeeded in #{elapsed}s.")
record('info', 'reset', "'systemctl restart' succeeded in #{elapsed}s.")
@@rst_counter = 0 # 成功时重置计数器
break
else
self.record("error", "reset", "'systemctl restart' failed with exitcode #{status.exitstatus} after #{elapsed}s.")
break
record('error', 'reset',
"'systemctl restart' failed with exitcode #{status.exitstatus} after #{elapsed}s.")
end
break
else # 子进程仍在运行 (WNOHANG 返回 nil)
if Time.now - tick_beg > PERSISTENCE_PERIOD then
self.record("warn", "reset",
"'systemctl restart' timed out after #{PERSISTENCE_PERIOD}s. Force-killing PID #{pid}...")
if Time.now - tick_beg > PERSISTENCE_PERIOD
record('warn', 'reset',
"'systemctl restart' timed out after #{PERSISTENCE_PERIOD}s. Force-killing PID #{pid}...")
system "kill -9 #{pid}"
self.record("warn", "reset", "Running 'systemctl kill minecraft' (last resort)...")
system "systemctl kill minecraft" # 没招了,毁灭吧
record('warn', 'reset', "Running 'systemctl kill minecraft' (last resort)...")
system 'systemctl kill minecraft' # 没招了,毁灭吧
sleep 0.5
self.record("info", "reset", "Running 'systemctl start minecraft' (rebirth)...")
system "systemctl start minecraft" # 重生
self.record("info", "reset", "Force-reset sequence completed.")
record('info', 'reset', "Running 'systemctl start minecraft' (rebirth)...")
system 'systemctl start minecraft' # 重生
record('info', 'reset', 'Force-reset sequence completed.')
break
end
end
# rubocop:enable Metrics/BlockLength
end
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# rubocop:enable Style/ClassVars
end