Class: Puma::Configuration
- Inherits:
-
Object
- Object
- Puma::Configuration
- 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 ‘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.clamp 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.
Defined Under Namespace
Classes: ConfigMiddleware, NotClampedError, NotLoadedError
Constant Summary collapse
- DEFAULTS =
{ auto_trim_time: 30, binds: ['tcp://[::]:9292'.freeze], debug: false, early_hints: nil, enable_keep_alives: true, environment: 'development'.freeze, fiber_per_request: !!ENV.fetch("PUMA_FIBER_PER_REQUEST", false), # Number of seconds to wait until we get the first data for the request. first_data_timeout: 30, force_shutdown_after: -1, http_content_length_limit: nil, # Number of seconds to wait until the next request before shutting down. idle_timeout: nil, io_selector_backend: :auto, log_requests: false, logger: STDOUT, # Limits how many requests a keep alive connection can make. # The connection will be closed after it reaches `max_keep_alive` # requests. max_io_threads: 0, max_keep_alive: 999, 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: 65, # PUMA_PERSISTENT_TIMEOUT prune_bundler: false, queue_requests: true, rackup: 'config.ru'.freeze, raise_exception_on_sigterm: true, reaping_time: 1, remote_address: :socket, silence_fork_callback_warning: false, silence_single_worker_warning: false, tag: File.basename(Dir.getwd), tcp_host: '::'.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, }
Instance Attribute Summary collapse
-
#_options ⇒ Object
readonly
Returns the value of attribute _options.
-
#events ⇒ Object
readonly
Returns the value of attribute events.
-
#hooks ⇒ Object
readonly
Returns the value of attribute hooks.
-
#plugins ⇒ Object
readonly
Returns the value of attribute plugins.
Class Method Summary collapse
- .default_tcp_bind(port = ) ⇒ Object
- .default_tcp_host ⇒ Object
- .ipv6_interface_available? ⇒ Boolean
- .random_token ⇒ Object
- .temp_path ⇒ Object
Instance Method Summary collapse
-
#app ⇒ Object
Load the specified rackup file, pull options from the rackup file, and set @app.
-
#app_configured? ⇒ Boolean
Indicate if there is a properly configured app.
-
#clamp ⇒ Object
Call once all configuration (included from rackup files) is loaded to finalize defaults and lock in the configuration.
- #config_files ⇒ Object
- #configure ⇒ Object
-
#environment ⇒ Object
Return which environment we’re running in.
- #final_options ⇒ Object
- #flatten ⇒ Object
- #flatten! ⇒ Object
-
#initialize(user_options = {}, default_options = {}, env = ENV, &block) ⇒ Configuration
constructor
A new instance of Configuration.
- #initialize_copy(other) ⇒ Object
- #load ⇒ Object
- #load_plugin(name) ⇒ Object
- #options ⇒ Object
- #puma_default_options(env = ENV) ⇒ Object
- #puma_options_from_env(env = ENV) ⇒ Object
- #rackup ⇒ Object
- #run_hooks(key, arg, log_writer, hook_data = nil) ⇒ Object
Constructor Details
#initialize(user_options = {}, default_options = {}, env = ENV, &block) ⇒ Configuration
Returns a new instance of Configuration.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/puma/configuration.rb', line 184 def initialize(={}, = {}, env = ENV, &block) = self.(env).merge(events: Events.new).merge() @_options = UserFileDefaultOptions.new(, ) @plugins = PluginLoader.new @events = @_options[:events] || Events.new @hooks = {} @user_dsl = DSL.new(@_options., self) @file_dsl = DSL.new(@_options., self) @default_dsl = DSL.new(@_options., self) @puma_bundler_pruned = env.key? 'PUMA_BUNDLER_PRUNED' if block configure(&block) end @loaded = false @clamped = false end |
Instance Attribute Details
#_options ⇒ Object (readonly)
Returns the value of attribute _options.
205 206 207 |
# File 'lib/puma/configuration.rb', line 205 def @_options end |
#events ⇒ Object (readonly)
Returns the value of attribute events.
205 206 207 |
# File 'lib/puma/configuration.rb', line 205 def events @events end |
#hooks ⇒ Object (readonly)
Returns the value of attribute hooks.
205 206 207 |
# File 'lib/puma/configuration.rb', line 205 def hooks @hooks end |
#plugins ⇒ Object (readonly)
Returns the value of attribute plugins.
205 206 207 |
# File 'lib/puma/configuration.rb', line 205 def plugins @plugins end |
Class Method Details
.default_tcp_bind(port = ) ⇒ Object
373 374 375 |
# File 'lib/puma/configuration.rb', line 373 def self.default_tcp_bind(port = DEFAULTS[:tcp_port]) URI::Generic.build(scheme: 'tcp', host: default_tcp_host, port: Integer(port)).to_s end |
.default_tcp_host ⇒ Object
369 370 371 |
# File 'lib/puma/configuration.rb', line 369 def self.default_tcp_host ipv6_interface_available? ? Const::UNSPECIFIED_IPV6 : Const::UNSPECIFIED_IPV4 end |
.ipv6_interface_available? ⇒ Boolean
377 378 379 380 381 382 383 384 |
# File 'lib/puma/configuration.rb', line 377 def self.ipv6_interface_available? Socket.getifaddrs.any? do |ifaddr| addr = ifaddr.addr addr&.ipv6? && !addr&.ipv6_loopback? end rescue StandardError false end |
.random_token ⇒ Object
393 394 395 396 397 |
# File 'lib/puma/configuration.rb', line 393 def self.random_token require 'securerandom' unless defined?(SecureRandom) SecureRandom.hex(16) end |
.temp_path ⇒ Object
386 387 388 389 390 391 |
# File 'lib/puma/configuration.rb', line 386 def self.temp_path require 'tmpdir' t = (Time.now.to_f * 1000).to_i "#{Dir.tmpdir}/puma-status-#{t}-#{$$}" end |
Instance Method Details
#app ⇒ Object
Load the specified rackup file, pull options from the rackup file, and set @app.
322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/puma/configuration.rb', line 322 def app found = [:app] || load_rackup if [:log_requests] require_relative 'commonlogger' logger = [:custom_logger] ? [:custom_logger] : [:logger] found = CommonLogger.new(found, logger) end ConfigMiddleware.new(self, found) end |
#app_configured? ⇒ Boolean
Indicate if there is a properly configured app
311 312 313 |
# File 'lib/puma/configuration.rb', line 311 def app_configured? [:app] || File.exist?(rackup) end |
#clamp ⇒ Object
Call once all configuration (included from rackup files) is loaded to finalize defaults and lock in the configuration.
This also calls load if it hasn’t been called yet.
285 286 287 288 289 290 291 292 293 294 |
# File 'lib/puma/configuration.rb', line 285 def clamp load unless @loaded run_mode_hooks @_options.finalize_values rewrite_unavailable_ipv6_binds! @clamped = true warn_hooks end |
#config_files ⇒ Object
266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
# File 'lib/puma/configuration.rb', line 266 def config_files raise NotLoadedError, "ensure load is called before accessing config_files" unless @loaded 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 ⇒ Object
213 214 215 216 217 218 219 |
# File 'lib/puma/configuration.rb', line 213 def configure yield @user_dsl, @file_dsl, @default_dsl ensure @user_dsl._offer_plugins @file_dsl._offer_plugins @default_dsl._offer_plugins end |
#environment ⇒ Object
Return which environment we’re running in
335 336 337 |
# File 'lib/puma/configuration.rb', line 335 def environment [:environment] end |
#final_options ⇒ Object
365 366 367 |
# File 'lib/puma/configuration.rb', line 365 def . end |
#flatten ⇒ Object
227 228 229 |
# File 'lib/puma/configuration.rb', line 227 def flatten dup.flatten! end |
#flatten! ⇒ Object
231 232 233 234 |
# File 'lib/puma/configuration.rb', line 231 def flatten! @_options = @_options.flatten self end |
#initialize_copy(other) ⇒ Object
221 222 223 224 225 |
# File 'lib/puma/configuration.rb', line 221 def initialize_copy(other) @conf = nil @cli_options = nil @_options = @_options.dup end |
#load ⇒ Object
260 261 262 263 264 |
# File 'lib/puma/configuration.rb', line 260 def load @loaded = true config_files.each { |config_file| @file_dsl._load_from(config_file) } @_options end |
#load_plugin(name) ⇒ Object
339 340 341 |
# File 'lib/puma/configuration.rb', line 339 def load_plugin(name) @plugins.create name end |
#options ⇒ Object
207 208 209 210 211 |
# File 'lib/puma/configuration.rb', line 207 def raise NotClampedError, "ensure clamp is called before accessing options" unless @clamped @_options end |
#puma_default_options(env = ENV) ⇒ Object
236 237 238 239 240 241 242 |
# File 'lib/puma/configuration.rb', line 236 def (env = ENV) defaults = DEFAULTS.dup defaults[:tcp_host] = self.class.default_tcp_host defaults[:binds] = [self.class.default_tcp_bind] (env).each { |k,v| defaults[k] = v if v } defaults end |
#puma_options_from_env(env = ENV) ⇒ Object
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/puma/configuration.rb', line 244 def (env = ENV) min = env['PUMA_MIN_THREADS'] || env['MIN_THREADS'] max = env['PUMA_MAX_THREADS'] || env['MAX_THREADS'] persistent_timeout = env['PUMA_PERSISTENT_TIMEOUT'] workers_env = env['WEB_CONCURRENCY'] workers = workers_env && workers_env.strip != "" ? parse_workers(workers_env.strip) : nil { min_threads: min && min != "" && Integer(min), max_threads: max && max != "" && Integer(max), persistent_timeout: persistent_timeout && persistent_timeout != "" && Integer(persistent_timeout), workers: workers, environment: env['APP_ENV'] || env['RACK_ENV'] || env['RAILS_ENV'], } end |
#rackup ⇒ Object
315 316 317 |
# File 'lib/puma/configuration.rb', line 315 def rackup [:rackup] end |
#run_hooks(key, arg, log_writer, hook_data = nil) ⇒ Object
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/puma/configuration.rb', line 346 def run_hooks(key, arg, log_writer, hook_data = nil) log_writer.debug { "Running #{key} hooks" } .all_of(key).each do || begin block = [:block] if id = [:id] hook_data[id] ||= Hash.new block.call arg, hook_data[id] else block.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 |