123456789_123456789_123456789_123456789_123456789_

Class: Puma::Configuration

Relationships & Source Files
Namespace Children
Classes:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
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 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.

Constant Summary

ConfigDefault - Included

DefaultRackup, DefaultTCPHost, DefaultTCPPort, DefaultWorkerCheckInterval, DefaultWorkerShutdownTimeout, DefaultWorkerTimeout

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(user_options = {}, default_options = {}, &block) ⇒ Configuration

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 141

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

Class Method Details

.random_token (private)

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 363

def self.random_token
  require 'securerandom' unless defined?(SecureRandom)

  SecureRandom.hex(16)
end

.temp_path

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 309

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

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 258

def app_configured?
  @options[:app] || File.exist?(rackup)
end

#options (readonly)

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 159

attr_reader :options, :plugins

#plugins (readonly)

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 159

attr_reader :options, :plugins

Instance Method Details

#app

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

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 269

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

#clamp

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

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 239

def clamp
  @options.finalize_values
end

#config_files

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 224

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

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 161

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

Version:

  • 5.0.0

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 185

def default_max_threads
  Puma.mri? ? 5 : 16
end

#environment

Return which environment we’re running in

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 282

def environment
  @options[:environment]
end

#environment_str

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 286

def environment_str
  environment.respond_to?(:call) ? environment.call : environment
end

#final_options

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 305

def final_options
  @options.final_options
end

#flatten

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 175

def flatten
  dup.flatten!
end

#flatten!

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 179

def flatten!
  @options = @options.flatten
  self
end

#infer_tag (private)

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 318

def infer_tag
  File.basename(Dir.getwd)
end

#initialize_copy(other)

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 169

def initialize_copy(other)
  @conf        = nil
  @cli_options = nil
  @options     = @options.dup
end

#load

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 218

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 290

def load_plugin(name)
  @plugins.create name
end

#load_rackup (private)

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 345

def load_rackup
  raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup)

  rack_app, rack_options = rack_builder.parse_file(rackup)
  rack_options = rack_options || {}

  @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

#puma_default_options

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 189

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_check_interval => DefaultWorkerCheckInterval,
    :worker_timeout => DefaultWorkerTimeout,
    :worker_boot_timeout => DefaultWorkerTimeout,
    :worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
    :worker_culling_strategy => :youngest,
    :remote_address => :socket,
    :tag => method(:infer_tag),
    :environment => -> { ENV['APP_ENV'] || 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

#rack_builder (private)

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

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 324

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

#rackup

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 262

def rackup
  @options[:rackup]
end

#run_hooks(key, arg, events)

[ GitHub ]

  
# File 'lib/puma/configuration.rb', line 294

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