diff --git a/History.md b/History.md index 93bd8467..83372dd8 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,7 @@ * Bugfixes * Add `#flush` and `#sync` methods to `Puma::NullIO` ([#2553]) + * Restore `sync=true` on `STDOUT` and `STDERR` streams #2557 ## 5.2.1 / 2021-02-05 diff --git a/lib/puma/configuration.rb b/lib/puma/configuration.rb index 3f0990bd..d7c18ad1 100644 --- a/lib/puma/configuration.rb +++ b/lib/puma/configuration.rb @@ -206,7 +206,8 @@ module Puma :first_data_timeout => Const::FIRST_DATA_TIMEOUT, :raise_exception_on_sigterm => true, :max_fast_inline => Const::MAX_FAST_INLINE, - :io_selector_backend => :auto + :io_selector_backend => :auto, + :mutate_stdout_and_stderr_to_sync_on_write => true, } end diff --git a/lib/puma/dsl.rb b/lib/puma/dsl.rb index ce73f16d..45511e07 100644 --- a/lib/puma/dsl.rb +++ b/lib/puma/dsl.rb @@ -888,5 +888,9 @@ module Puma def io_selector_backend(backend) @options[:io_selector_backend] = backend.to_sym end + + def mutate_stdout_and_stderr_to_sync_on_write(enabled=true) + @options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled + end end end diff --git a/lib/puma/runner.rb b/lib/puma/runner.rb index c4379bf8..30c4a89b 100644 --- a/lib/puma/runner.rb +++ b/lib/puma/runner.rb @@ -126,6 +126,11 @@ module Puma STDERR.puts "=== puma startup: #{Time.now} ===" STDERR.flush unless STDERR.sync end + + if @options[:mutate_stdout_and_stderr_to_sync_on_write] + STDOUT.sync = true + STDERR.sync = true + end end def load_and_bind diff --git a/test/rackup/write_to_stdout.ru b/test/rackup/write_to_stdout.ru new file mode 100644 index 00000000..880d3d2e --- /dev/null +++ b/test/rackup/write_to_stdout.ru @@ -0,0 +1,6 @@ +app = lambda do |env| + $stdout.write "hello\n" + [200, {"Content-Type" => "text/plain"}, ["Hello World"]] +end + +run app diff --git a/test/test_integration_single.rb b/test/test_integration_single.rb index 2d2ce3a2..1d39fb04 100644 --- a/test/test_integration_single.rb +++ b/test/test_integration_single.rb @@ -163,4 +163,11 @@ class TestIntegrationSingle < TestIntegration assert(!File.file?("t2-pid")) assert_equal("Puma is started\n", out) end + + def test_application_logs_are_flushed_on_write + cli_server 'test/rackup/write_to_stdout.ru' + read_body connect + log_line = @server.gets + assert_equal "hello\n", log_line + end end