class Puma::Configuration

The main configuration class of Puma.

It can be initialized with a set of “user” options and “default” options. Defaults will be merged with `Configuration.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 `Puma::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 maps `port` and `host` calls to `:binds`

config = Configuration.new({}) do |user_config, file_config, default_config|
  user_config.port 3003
end
config.load
puts config.options[: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.

Attributes

options[R]
plugins[R]

Public Class Methods

new(user_options={}, default_options = {}, &block) click to toggle source
# File lib/puma/configuration.rb, line 140
def initialize(user_options={}, default_options = {}, &block)
  default_options = self.puma_default_options.merge(default_options)

  @options     = UserFileDefaultOptions.new(user_options, default_options)
  @plugins     = PluginLoader.new
  @user_dsl    = DSL.new(@options.user_options, self)
  @file_dsl    = DSL.new(@options.file_options, self)
  @default_dsl = DSL.new(@options.default_options, self)

  if !@options[:prune_bundler]
    default_options[:preload_app] = (@options[:workers] > 1) && Puma.forkable?
  end

  if block
    configure(&block)
  end
end
temp_path() click to toggle source
# File lib/puma/configuration.rb, line 306
def self.temp_path
  require 'tmpdir'

  t = (Time.now.to_f * 1000).to_i
  "#{Dir.tmpdir}/puma-status-#{t}-#{$$}"
end

Private Class Methods

random_token() click to toggle source
# File lib/puma/configuration.rb, line 358
def self.random_token
  require 'securerandom' unless defined?(SecureRandom)

  SecureRandom.hex(16)
end

Public Instance Methods

app() click to toggle source

Load the specified rackup file, pull options from the rackup file, and set @app.

# File lib/puma/configuration.rb, line 266
def app
  found = options[:app] || load_rackup

  if @options[:log_requests]
    require 'puma/commonlogger'
    logger = @options[:logger]
    found = CommonLogger.new(found, logger)
  end

  ConfigMiddleware.new(self, found)
end
app_configured?() click to toggle source

Indicate if there is a properly configured app

# File lib/puma/configuration.rb, line 255
def app_configured?
  @options[:app] || File.exist?(rackup)
end
clamp() click to toggle source

Call once all configuration (included from rackup files) is loaded to flesh out any defaults

# File lib/puma/configuration.rb, line 236
def clamp
  @options.finalize_values
end
config_files() click to toggle source
# File lib/puma/configuration.rb, line 221
def config_files
  files = @options.all_of(:config_files)

  return [] if files == ['-']
  return files if files.any?

  first_default_file = %W(config/puma/#{environment_str}.rb config/puma.rb).find do |f|
    File.exist?(f)
  end

  [first_default_file]
end
configure() { |user_dsl, file_dsl, default_dsl| ... } click to toggle source
# File lib/puma/configuration.rb, line 160
def configure
  yield @user_dsl, @file_dsl, @default_dsl
ensure
  @user_dsl._offer_plugins
  @file_dsl._offer_plugins
  @default_dsl._offer_plugins
end
default_max_threads() click to toggle source

@version 5.0.0

# File lib/puma/configuration.rb, line 184
def default_max_threads
  Puma.mri? ? 5 : 16
end
environment() click to toggle source

Return which environment we're running in

# File lib/puma/configuration.rb, line 279
def environment
  @options[:environment]
end
environment_str() click to toggle source
# File lib/puma/configuration.rb, line 283
def environment_str
  environment.respond_to?(:call) ? environment.call : environment
end
final_options() click to toggle source
# File lib/puma/configuration.rb, line 302
def final_options
  @options.final_options
end
flatten() click to toggle source
# File lib/puma/configuration.rb, line 174
def flatten
  dup.flatten!
end
flatten!() click to toggle source
# File lib/puma/configuration.rb, line 178
def flatten!
  @options = @options.flatten
  self
end
initialize_copy(other) click to toggle source
# File lib/puma/configuration.rb, line 168
def initialize_copy(other)
  @conf        = nil
  @cli_options = nil
  @options     = @options.dup
end
load() click to toggle source
# File lib/puma/configuration.rb, line 215
def load
  config_files.each { |config_file| @file_dsl._load_from(config_file) }

  @options
end
load_plugin(name) click to toggle source
# File lib/puma/configuration.rb, line 287
def load_plugin(name)
  @plugins.create name
end
puma_default_options() click to toggle source
# File lib/puma/configuration.rb, line 188
def puma_default_options
  {
    :min_threads => Integer(ENV['PUMA_MIN_THREADS'] || ENV['MIN_THREADS'] || 0),
    :max_threads => Integer(ENV['PUMA_MAX_THREADS'] || ENV['MAX_THREADS'] || default_max_threads),
    :log_requests => false,
    :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,
    :worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
    :remote_address => :socket,
    :tag => method(:infer_tag),
    :environment => -> { ENV['RACK_ENV'] || ENV['RAILS_ENV'] || "development" },
    :rackup => DefaultRackup,
    :logger => STDOUT,
    :persistent_timeout => Const::PERSISTENT_TIMEOUT,
    :first_data_timeout => Const::FIRST_DATA_TIMEOUT,
    :raise_exception_on_sigterm => true,
    :max_fast_inline => Const::MAX_FAST_INLINE,
    :io_selector_backend => :auto,
    :mutate_stdout_and_stderr_to_sync_on_write => true,
  }
end
rackup() click to toggle source
# File lib/puma/configuration.rb, line 259
def rackup
  @options[:rackup]
end
run_hooks(key, arg, events) click to toggle source
# File lib/puma/configuration.rb, line 291
def run_hooks(key, arg, events)
  @options.all_of(key).each do |b|
    begin
      b.call arg
    rescue => e
      events.log "WARNING hook #{key} failed with exception (#{e.class}) #{e.message}"
      events.debug e.backtrace.join("\n")
    end
  end
end

Private Instance Methods

infer_tag() click to toggle source
# File lib/puma/configuration.rb, line 315
def infer_tag
  File.basename(Dir.getwd)
end
load_rackup() click to toggle source
# File lib/puma/configuration.rb, line 342
def load_rackup
  raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup)

  rack_app, rack_options = rack_builder.parse_file(rackup)
  @options.file_options.merge!(rack_options)

  config_ru_binds = []
  rack_options.each do |k, v|
    config_ru_binds << v if k.to_s.start_with?("bind")
  end

  @options.file_options[:binds] = config_ru_binds unless config_ru_binds.empty?

  rack_app
end
rack_builder() click to toggle source

Load and use the normal Rack builder if we can, otherwise fallback to our minimal version.

# File lib/puma/configuration.rb, line 321
def rack_builder
  # Load bundler now if we can so that we can pickup rack from
  # a Gemfile
  if ENV.key? 'PUMA_BUNDLER_PRUNED'
    begin
      require 'bundler/setup'
    rescue LoadError
    end
  end

  begin
    require 'rack'
    require 'rack/builder'
  rescue LoadError
    # ok, use builtin version
    return Puma::Rack::Builder
  else
    return ::Rack::Builder
  end
end