diff --git a/lib/puma/plugin/solid_queue.rb b/lib/puma/plugin/solid_queue.rb index 8a7aea28b..3fff5d417 100644 --- a/lib/puma/plugin/solid_queue.rb +++ b/lib/puma/plugin/solid_queue.rb @@ -129,5 +129,9 @@ def puma_dead? def log(...) log_writer.log(...) + rescue Errno::EIO, Errno::EPIPE, Errno::EBADF + # The controlling terminal can disappear, or the output pipe close, before + # the monitor thread shuts down the child process. Keep shutdown moving + # even when logging cannot. end end diff --git a/test/unit/puma_plugin_test.rb b/test/unit/puma_plugin_test.rb new file mode 100644 index 000000000..24325ef8f --- /dev/null +++ b/test/unit/puma_plugin_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "test_helper" +require "puma/plugin/solid_queue" + +class PumaPluginTest < ActiveSupport::TestCase + class ClosedOutputLogWriter + def initialize(error) + @error = error + end + + def log(...) + raise @error + end + end + + [ Errno::EIO, Errno::EPIPE, Errno::EBADF ].each do |error| + test "monitor still stops the process when shutdown logging fails with #{error}" do + plugin = Puma::Plugins.find("solid_queue").new + plugin.instance_variable_set(:@log_writer, ClosedOutputLogWriter.new(error)) + + plugin.stubs(:puma_dead?).returns(true) + Process.expects(:kill).with(:INT, Process.pid) + + plugin.send(:monitor, :puma_dead?, "Detected Puma has gone away, stopping Solid Queue...") + end + end +end