Class: Puma::Configuration
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Inherits: | Object |
Defined in: | lib/puma/configuration.rb |
Overview
The main configuration class of ::Puma
.
It can be initialized with a set of “user” options and “default” options. Defaults will be merged with #puma_default_options.
This class works together with 2 main other classes the UserFileDefaultOptions
which stores configuration options in order so the precedence is that user set configuration wins over “file” based configuration wins over “default” configuration. These configurations are set via the DSL
class. This class powers the ::Puma
config file syntax and does double duty as a configuration DSL
used by the CLI
and ::Puma
rack handler.
It also handles loading plugins.
- Note:
-
:port
and:host
are not valid keys. By the time they make it to the configuration options they are expected to be incorporated into a:binds
key. Under the hood the DSL mapsport
andhost
calls to:binds
config = Configuration.new({}) do |user_config, file_config, default_config| user_config.port 3003 end config.load puts config. [:port] # => 3003
It is expected that #load is called on the configuration instance after setting config. This method expands any values in config_file
and puts them into the correct configuration option hash.
Once all configuration is complete it is expected that #clamp will be called on the instance. This will expand any procs stored under “default” values. This is done because an environment variable may have been modified while loading configuration files.
Constant Summary
-
DEFAULTS =
# File 'lib/puma/configuration.rb', line 128{ auto_trim_time: 30, binds: ['tcp://0.0.0.0:9292'.freeze], clean_thread_locals: false, debug: false, enable_keep_alives: true, early_hints: nil, environment: 'development'.freeze, # Number of seconds to wait until we get the first data for the request. first_data_timeout: 30, # Number of seconds to wait until the next request before shutting down. idle_timeout: nil, io_selector_backend: :auto, log_requests: false, logger: STDOUT, # How many requests to attempt inline before sending a client back to # the reactor to be subject to normal ordering. The idea here is that # we amortize the cost of going back to the reactor for a well behaved # but very "greedy" client across 10 requests. This prevents a not # well behaved client from monopolizing the thread forever. max_fast_inline: 10, max_threads: Puma.mri? ? 5 : 16, min_threads: 0, mode: :http, mutate_stdout_and_stderr_to_sync_on_write: true, out_of_band: [], # Number of seconds for another request within a persistent session. persistent_timeout: 20, queue_requests: true, rackup: 'config.ru'.freeze, raise_exception_on_sigterm: true, reaping_time: 1, remote_address: :socket, silence_single_worker_warning: false, silence_fork_callback_warning: false, tag: File.basename(Dir.getwd), tcp_host: '0.0.0.0'.freeze, tcp_port: 9292, wait_for_less_busy_worker: 0.005, worker_boot_timeout: 60, worker_check_interval: 5, worker_culling_strategy: :youngest, worker_shutdown_timeout: 30, worker_timeout: 60, workers: 0, http_content_length_limit: nil }
Class Method Summary
Instance Attribute Summary
-
#app_configured? ⇒ Boolean
readonly
Indicate if there is a properly configured app.
- #options readonly
- #plugins readonly
Instance Method Summary
-
#app
Load the specified rackup file, pull options from the rackup file, and set @app.
-
#clamp
Call once all configuration (included from rackup files) is loaded to flesh out any defaults.
- #config_files
- #configure
-
#environment
Return which environment we’re running in.
- #final_options
- #flatten
- #flatten!
- #initialize_copy(other)
- #load
- #load_plugin(name)
- #puma_default_options(env = ENV)
- #puma_options_from_env(env = ENV)
- #rackup
- #run_hooks(key, arg, log_writer, hook_data = nil)
- #load_rackup private
-
#rack_builder
private
Load and use the normal
Rack
builder if we can, otherwise fallback to our minimal version. - #require_processor_counter private
Constructor Details
.new(user_options = {}, default_options = {}, env = ENV, &block) ⇒ Configuration
# File 'lib/puma/configuration.rb', line 176
def initialize(={}, = {}, env = ENV, &block) = self. (env).merge( ) @options = UserFileDefaultOptions.new(, ) @plugins = PluginLoader.new @user_dsl = DSL.new(@options., self) @file_dsl = DSL.new(@options., self) @default_dsl = DSL.new(@options., self) if !@options[:prune_bundler] [:preload_app] = (@options[:workers] > 1) && Puma.forkable? end @puma_bundler_pruned = env.key? 'PUMA_BUNDLER_PRUNED' if block configure(&block) end end
Class Method Details
.random_token (private)
[ GitHub ]# File 'lib/puma/configuration.rb', line 401
def self.random_token require 'securerandom' unless defined?(SecureRandom) SecureRandom.hex(16) end
.temp_path
[ GitHub ]# File 'lib/puma/configuration.rb', line 342
def self.temp_path require 'tmpdir' t = (Time.now.to_f * 1000).to_i "#{Dir.tmpdir}/puma-status-#{t}-#{$$}" end
Instance Attribute Details
#app_configured? ⇒ Boolean
(readonly)
Indicate if there is a properly configured app
#options (readonly)
[ GitHub ]# File 'lib/puma/configuration.rb', line 196
attr_reader :, :plugins
#plugins (readonly)
[ GitHub ]# File 'lib/puma/configuration.rb', line 196
attr_reader :, :plugins
Instance Method Details
#app
Load the specified rackup file, pull options from the rackup file, and set @app.
# File 'lib/puma/configuration.rb', line 296
def app found = [:app] || load_rackup if @options[:log_requests] require_relative 'commonlogger' logger = @options[:logger] found = CommonLogger.new(found, logger) end ConfigMiddleware.new(self, found) end
#clamp
Call once all configuration (included from rackup files) is loaded to flesh out any defaults
# File 'lib/puma/configuration.rb', line 266
def clamp @options.finalize_values end
#config_files
[ GitHub ]# File 'lib/puma/configuration.rb', line 251
def config_files files = @options.all_of(:config_files) return [] if files == ['-'] return files if files.any? first_default_file = %W(config/puma/#{@options[:environment]}.rb config/puma.rb).find do |f| File.exist?(f) end [first_default_file] end
#configure
[ GitHub ]# File 'lib/puma/configuration.rb', line 198
def configure yield @user_dsl, @file_dsl, @default_dsl ensure @user_dsl._offer_plugins @file_dsl._offer_plugins @default_dsl._offer_plugins end
#environment
Return which environment we’re running in
# File 'lib/puma/configuration.rb', line 309
def environment @options[:environment] end
#final_options
[ GitHub ]# File 'lib/puma/configuration.rb', line 338
def @options. end
#flatten
[ GitHub ]# File 'lib/puma/configuration.rb', line 212
def flatten dup.flatten! end
#flatten!
[ GitHub ]# File 'lib/puma/configuration.rb', line 216
def flatten! @options = @options.flatten self end
#initialize_copy(other)
[ GitHub ]# File 'lib/puma/configuration.rb', line 206
def initialize_copy(other) @conf = nil @cli_options = nil @options = @options.dup end
#load
[ GitHub ]# File 'lib/puma/configuration.rb', line 245
def load config_files.each { |config_file| @file_dsl._load_from(config_file) } @options end
#load_plugin(name)
[ GitHub ]# File 'lib/puma/configuration.rb', line 313
def load_plugin(name) @plugins.create name end
#load_rackup (private)
[ GitHub ]# File 'lib/puma/configuration.rb', line 383
def load_rackup raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup) rack_app, = rack_builder.parse_file(rackup) = || {} @options. .merge!( ) config_ru_binds = [] .each do |k, v| config_ru_binds << v if k.to_s.start_with?("bind") end @options. [:binds] = config_ru_binds unless config_ru_binds.empty? rack_app end
#puma_default_options(env = ENV)
[ GitHub ]# File 'lib/puma/configuration.rb', line 221
def (env = ENV) defaults = DEFAULTS.dup (env).each { |k,v| defaults[k] = v if v } defaults end
#puma_options_from_env(env = ENV)
[ GitHub ]# File 'lib/puma/configuration.rb', line 227
def (env = ENV) min = env['PUMA_MIN_THREADS'] || env['MIN_THREADS'] max = env['PUMA_MAX_THREADS'] || env['MAX_THREADS'] workers = if env['WEB_CONCURRENCY'] == 'auto' require_processor_counter ::Concurrent.available_processor_count else env['WEB_CONCURRENCY'] end { min_threads: min && min != "" && Integer(min), max_threads: max && max != "" && Integer(max), workers: workers && workers != "" && Integer(workers), environment: env['APP_ENV'] || env['RACK_ENV'] || env['RAILS_ENV'], } end
#rack_builder (private)
Load and use the normal Rack
builder if we can, otherwise fallback to our minimal version.
# File 'lib/puma/configuration.rb', line 363
def rack_builder # Load bundler now if we can so that we can pickup rack from # a Gemfile if @puma_bundler_pruned begin require 'bundler/setup' rescue LoadError end end begin require 'rack' require 'rack/builder' ::Rack::Builder rescue LoadError require_relative 'rack/builder' Puma::Rack::Builder end end
#rackup
[ GitHub ]# File 'lib/puma/configuration.rb', line 289
def rackup @options[:rackup] end
#require_processor_counter (private)
[ GitHub ]# File 'lib/puma/configuration.rb', line 351
def require_processor_counter require 'concurrent/utility/processor_counter' rescue LoadError warn <<~MESSAGE WEB_CONCURRENCY=auto requires the "concurrent-ruby" gem to be installed. Please add "concurrent-ruby" to your Gemfile. MESSAGE raise end
#run_hooks(key, arg, log_writer, hook_data = nil)
# File 'lib/puma/configuration.rb', line 320
def run_hooks(key, arg, log_writer, hook_data = nil) log_writer.debug "Running #{key} hooks" @options.all_of(key).each do |b| begin if Array === b hook_data[b[1]] ||= Hash.new b[0].call arg, hook_data[b[1]] else b.call arg end rescue => e log_writer.log "WARNING hook #{key} failed with exception (#{e.class}) #{e.}" log_writer.debug e.backtrace.join("\n") end end end