diff --git a/History.md b/History.md index 159b889dca..9c9a4dd182 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,7 @@ * Features * Your feature goes here (#Github Number) + * Uses stdio `flush` to avoiding mutating $stdout and $stderr `with sync=true` ([#2486]) * Prints the loaded configuration if the environment variable `PUMA_LOG_CONFIG` is present ([#2472]) * Integrate with systemd's watchdog and notification features ([#2438]) * Adds max_fast_inline as a configuration option for the Server object ([#2406]) diff --git a/lib/puma/error_logger.rb b/lib/puma/error_logger.rb index 7a2bb462b0..4b1f183add 100644 --- a/lib/puma/error_logger.rb +++ b/lib/puma/error_logger.rb @@ -15,7 +15,6 @@ class ErrorLogger def initialize(ioerr) @ioerr = ioerr - @ioerr.sync = true @debug = ENV.key? 'PUMA_DEBUG' end @@ -32,7 +31,7 @@ def self.stdio # and before all remaining info. # def info(options={}) - ioerr.puts title(options) + log title(options) end # Print occured error details only if @@ -54,7 +53,7 @@ def debug(options={}) string_block << request_dump(req) if request_parsed?(req) string_block << error.backtrace if error - ioerr.puts string_block.join("\n") + log string_block.join("\n") end def title(options={}) @@ -93,5 +92,13 @@ def request_headers(req) def request_parsed?(req) req && req.env[REQUEST_METHOD] end + + private + + def log(str) + ioerr.puts str + + ioerr.flush unless ioerr.sync + end end end diff --git a/lib/puma/events.rb b/lib/puma/events.rb index 29280075d2..f96d553845 100644 --- a/lib/puma/events.rb +++ b/lib/puma/events.rb @@ -30,9 +30,6 @@ def initialize(stdout, stderr) @stdout = stdout @stderr = stderr - @stdout.sync = true - @stderr.sync = true - @debug = ENV.key? 'PUMA_DEBUG' @error_logger = ErrorLogger.new(@stderr) @@ -66,6 +63,8 @@ def register(hook, obj=nil, &blk) # def log(str) @stdout.puts format(str) if @stdout.respond_to? :puts + + @stdout.flush unless @stdout.sync rescue Errno::EPIPE end diff --git a/lib/puma/runner.rb b/lib/puma/runner.rb index e3e8cfdfbf..af3996d958 100644 --- a/lib/puma/runner.rb +++ b/lib/puma/runner.rb @@ -106,8 +106,8 @@ def redirect_io end STDOUT.reopen stdout, (append ? "a" : "w") - STDOUT.sync = true STDOUT.puts "=== puma startup: #{Time.now} ===" + STDOUT.flush unless STDOUT.sync end if stderr @@ -116,8 +116,8 @@ def redirect_io end STDERR.reopen stderr, (append ? "a" : "w") - STDERR.sync = true STDERR.puts "=== puma startup: #{Time.now} ===" + STDERR.flush unless STDERR.sync end end diff --git a/test/test_error_logger.rb b/test/test_error_logger.rb index 38aba15522..08be915803 100644 --- a/test/test_error_logger.rb +++ b/test/test_error_logger.rb @@ -10,6 +10,14 @@ def test_stdio assert_equal STDERR, error_logger.ioerr end + + def test_stdio_respects_sync + error_logger = Puma::ErrorLogger.stdio + + assert_equal STDERR.sync, error_logger.ioerr.sync + assert_equal STDERR, error_logger.ioerr + end + def test_info_with_only_error _, err = capture_io do Puma::ErrorLogger.stdio.info(error: StandardError.new('ready')) diff --git a/test/test_events.rb b/test/test_events.rb index d0da584cfb..ddd9659cdf 100644 --- a/test/test_events.rb +++ b/test/test_events.rb @@ -24,6 +24,15 @@ def test_stdio assert_equal STDERR, events.stderr end + def test_stdio_respects_sync + events = Puma::Events.stdio + + assert_equal STDOUT.sync, events.stdout.sync + assert_equal STDERR.sync, events.stderr.sync + assert_equal STDOUT, events.stdout + assert_equal STDERR, events.stderr + end + def test_register_callback_with_block res = false