Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print warning when running one-worker cluster #2565

Merged
merged 4 commits into from Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions History.md
Expand Up @@ -2,6 +2,7 @@

* Features
* Your feature goes here <Most recent on the top, like GitHub> (#Github Number)
* Warn when running Cluster mode with a single worker (#2565)

* Bugfixes
* Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
Expand Down
11 changes: 11 additions & 0 deletions lib/puma/cluster.rb
Expand Up @@ -382,6 +382,8 @@ def run

log "Use Ctrl-C to stop"

single_worker_warning

redirect_io

Plugins.fire_background
Expand Down Expand Up @@ -470,6 +472,15 @@ def run

private

def single_worker_warning
return if @options[:workers] != 1 || @options[:silence_single_worker_warning]

log "! WARNING: Detected running cluster mode with 1 worker."
log "! Running Puma in cluster mode with a single worker is often a misconfiguration."
log "! Consider running Puma in single-mode in order to reduce memory overhead."
nateberkopec marked this conversation as resolved.
Show resolved Hide resolved
log "! Set the `silence_single_worker_warning` option to silence this warning message."
end

# loops thru @workers, removing workers that exited, and calling
# `#term` if needed
def wait_workers
Expand Down
1 change: 1 addition & 0 deletions lib/puma/configuration.rb
Expand Up @@ -193,6 +193,7 @@ def puma_default_options
:debug => false,
:binds => ["tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"],
:workers => Integer(ENV['WEB_CONCURRENCY'] || 0),
:silence_single_worker_warning => false,
:mode => :http,
:worker_timeout => DefaultWorkerTimeout,
:worker_boot_timeout => DefaultWorkerTimeout,
Expand Down
7 changes: 7 additions & 0 deletions lib/puma/dsl.rb
Expand Up @@ -482,6 +482,13 @@ def workers(count)
@options[:workers] = count.to_i
end

# Disable warning message when running in cluster mode with a single worker.
#
# @note Cluster mode only.
def silence_single_worker_warning
@options[:silence_single_worker_warning] = true
end

# Code to run immediately before master process
# forks workers (once on boot). These hooks can block if necessary
# to wait for background operations unknown to Puma to finish before
Expand Down
16 changes: 16 additions & 0 deletions test/test_config.rb
Expand Up @@ -342,6 +342,22 @@ def test_final_options_returns_merged_options
assert_equal 2, conf.final_options[:max_threads]
end

def test_silence_single_worker_warning_default
conf = Puma::Configuration.new
conf.load

assert_equal false, conf.options[:silence_single_worker_warning]
end

def test_silence_single_worker_warning_overwrite
conf = Puma::Configuration.new do |c|
c.silence_single_worker_warning
end
conf.load

assert_equal true, conf.options[:silence_single_worker_warning]
end

private

def assert_run_hooks(hook_name, options = {})
Expand Down
22 changes: 22 additions & 0 deletions test/test_integration_cluster.rb
Expand Up @@ -313,6 +313,28 @@ def test_application_is_loaded_exactly_once_if_using_preload_app
assert_equal 0, worker_load_count
end

def test_warning_message_outputted_when_single_worker
cli_server "-w 1 test/rackup/hello.ru"

output = []
while (line = @server.gets) && line !~ /Worker \d \(PID/
output << line
end

assert_match /WARNING: Detected running cluster mode with 1 worker/, output.join
end

def test_warning_message_not_outputted_when_single_worker_silenced
cli_server "-w 1 test/rackup/hello.ru", config: "silence_single_worker_warning"

output = []
while (line = @server.gets) && line !~ /Worker \d \(PID/
output << line
end

refute_match /WARNING: Detected running cluster mode with 1 worker/, output.join
end

private

def worker_timeout(timeout, iterations, config)
Expand Down