From 09e7855eea52a24bb08a5361d937d936daccb5c7 Mon Sep 17 00:00:00 2001 From: Ivan Zakharanka Date: Mon, 27 Jul 2026 13:07:59 +0200 Subject: [PATCH] [ROMEO-1265] Exit cleanly on SIGTERM received during boot Booting the application can take long enough that a termination signal arrives before Runner installs its graceful signal handling, so the process dies non-gracefully and the orchestrator reports a crash. Install a minimal SIGTERM trap before boot_system; Runner replaces it with the full graceful shutdown once boot completes. Co-Authored-By: Claude Opus 4.7 --- CHANGELOG.md | 5 +++++ lib/eventboss/cli.rb | 11 +++++++++++ lib/eventboss/version.rb | 2 +- spec/eventboss/cli_spec.rb | 29 +++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbdd00c..017c70f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.9.9] + +### Fixed +- Exit cleanly on SIGTERM received during application boot, before the runner installs its graceful signal handling, so a shutdown mid-boot is no longer reported as a crash + ## [1.9.8] - Improve performance by reusing SNS client diff --git a/lib/eventboss/cli.rb b/lib/eventboss/cli.rb index 9e2f265..3b7d1c0 100644 --- a/lib/eventboss/cli.rb +++ b/lib/eventboss/cli.rb @@ -30,6 +30,8 @@ def parse(args = ARGV) end def run + setup_boot_signal_traps + boot_system Eventboss.logger.info('Starting eventboss...') @@ -39,6 +41,15 @@ def run private + # Booting the application (e.g. loading Rails) can take long enough that a + # termination signal arrives before Runner installs its graceful signal + # handling. Without a handler the process dies non-gracefully and is + # reported as a crash. Until Runner takes over, exit cleanly on SIGTERM so + # a shutdown mid-boot is not treated as a failure. + def setup_boot_signal_traps + Signal.trap('SIGTERM') { exit 0 } + end + def boot_system require 'rails' if ::Rails::VERSION::MAJOR < 4 diff --git a/lib/eventboss/version.rb b/lib/eventboss/version.rb index b1c4410..b4a10a0 100644 --- a/lib/eventboss/version.rb +++ b/lib/eventboss/version.rb @@ -1,3 +1,3 @@ module Eventboss - VERSION = "1.9.8" + VERSION = "1.9.9" end diff --git a/spec/eventboss/cli_spec.rb b/spec/eventboss/cli_spec.rb index bcab797..8e16a47 100644 --- a/spec/eventboss/cli_spec.rb +++ b/spec/eventboss/cli_spec.rb @@ -102,5 +102,34 @@ expect { subject.run }.to raise_error LoadError end end + + describe 'when SIGTERM is received during boot' do + let(:default_sigterm_signal) { Signal.trap 'SIGTERM', 'SYSTEM_DEFAULT' } + + after { Signal.trap 'SIGTERM', default_sigterm_signal } + + it 'exits with status 0 instead of crashing' do + reader, writer = IO.pipe + + pid = fork do + reader.close + allow(subject).to receive(:boot_system) do + writer.puts 'booting' + sleep 5 + end + allow(Eventboss).to receive(:launch) + + subject.run + end + + writer.close + reader.gets + + Process.kill 'SIGTERM', pid + _, status = Process.wait2(pid) + + expect(status.exitstatus).to eq 0 + end + end end end