Class: Pitchfork::Configurator
- Inherits:
-
Object
- Object
- Pitchfork::Configurator
show all
- Includes:
- Pitchfork
- Defined in:
- lib/pitchfork/configurator.rb
Overview
Constant Summary
collapse
- RACKUP =
used to stash stuff for deferred processing of cli options in config.ru. Do not rely on this being around later on…
{
:host => Pitchfork::Const::DEFAULT_HOST,
:port => Pitchfork::Const::DEFAULT_PORT,
:set_listener => false,
:options => { :listeners => [] }
}
- DEFAULTS =
{
:soft_timeout => 20,
:cleanup_timeout => 2,
:spawn_timeout => 10,
:timeout_signal => -> (_pid) { :KILL },
:timeout => 22,
:logger => default_logger,
:worker_processes => 1,
:before_fork => nil,
:after_worker_fork => lambda { |server, worker|
server.logger.info("worker=#{worker.nr} gen=#{worker.generation} pid=#{$$} spawned")
},
:after_mold_fork => lambda { |server, worker|
server.logger.info("mold gen=#{worker.generation} pid=#{$$} spawned")
},
:before_worker_exit => nil,
:after_worker_exit => lambda { |server, worker, status|
m = if worker.nil?
"repead unknown process (#{status.inspect})"
elsif worker.mold?
"mold pid=#{worker.pid rescue 'unknown'} gen=#{worker.generation rescue 'unknown'} reaped (#{status.inspect})"
elsif worker.service?
"service pid=#{worker.pid rescue 'unknown'} gen=#{worker.generation rescue 'unknown'} reaped (#{status.inspect})"
else
"worker=#{worker.nr rescue 'unknown'} pid=#{worker.pid rescue 'unknown'} gen=#{worker.generation rescue 'unknown'} reaped (#{status.inspect})"
end
if status.success?
server.logger.info(m)
else
server.logger.error(m)
end
},
:after_worker_ready => lambda { |server, worker|
server.logger.info("worker=#{worker.nr} gen=#{worker.generation} ready")
},
:after_monitor_ready => lambda { |server|
server.logger.info("Monitor pid=#{Process.pid} ready")
},
:after_worker_timeout => nil,
:after_worker_hard_timeout => nil,
:after_request_complete => nil,
:early_hints => false,
:refork_condition => nil,
:check_client_connection => false,
:rewindable_input => true,
:client_body_buffer_size => Pitchfork::Const::MAX_BODY,
:before_service_worker_ready => nil,
:before_service_worker_exit => nil,
}
Constants included
from Pitchfork
BootFailure, ClientShutdown, FORK_LOCK, ForkFailure, REFORKING_AVAILABLE, VERSION
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#[](key) ⇒ Object
-
#after_mold_fork(*args, &block) ⇒ Object
-
#after_monitor_ready(*args, &block) ⇒ Object
-
#after_request_complete(*args, &block) ⇒ Object
-
#after_worker_exit(*args, &block) ⇒ Object
-
#after_worker_fork(*args, &block) ⇒ Object
-
#after_worker_hard_timeout(*args, &block) ⇒ Object
-
#after_worker_ready(*args, &block) ⇒ Object
-
#after_worker_timeout(*args, &block) ⇒ Object
-
#before_fork(*args, &block) ⇒ Object
-
#before_service_worker_exit(&block) ⇒ Object
-
#before_service_worker_ready(&block) ⇒ Object
-
#before_worker_exit(*args, &block) ⇒ Object
-
#check_client_connection(bool) ⇒ Object
-
#client_body_buffer_size(bytes) ⇒ Object
-
#commit!(server, options = {}) ⇒ Object
-
#early_hints(bool) ⇒ Object
-
#expand_addr(address) ⇒ Object
expands “unix:path/to/foo” to a socket relative to the current path expands pathnames of sockets if relative to “~” or “~username” expands “*:port and ”:port“ to ”0.0.0.0:port“.
-
#initialize(defaults = {}) ⇒ Configurator
constructor
-
#listen(address, options = {}) ⇒ Object
-
#listeners(addresses) ⇒ Object
sets listeners to the given addresses
, replacing or augmenting the current set.
-
#load(merge_defaults = true) ⇒ Object
-
#logger(obj) ⇒ Object
-
#refork_after(limits) ⇒ Object
Defines the number of requests per-worker after which a new generation should be spawned.
-
#rewindable_input(bool) ⇒ Object
-
#spawn_timeout(seconds) ⇒ Object
-
#timeout(seconds, cleanup: 2) ⇒ Object
-
#timeout_signal(*args, &block) ⇒ Object
-
#worker_processes(nr) ⇒ Object
Methods included from Pitchfork
builder, clean_fork, listener_names, log_error, prevent_fork, socketpair, time_now
Constructor Details
#initialize(defaults = {}) ⇒ Configurator
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/pitchfork/configurator.rb', line 85
def initialize(defaults = {}) self.set = Hash.new(:unset)
@use_defaults = defaults.delete(:use_defaults)
self.config_file = defaults.delete(:config_file)
set.merge!(DEFAULTS) if @use_defaults
defaults.each { |key, value| self.__send__(key, value) }
Hash === set[:listener_opts] or
set[:listener_opts] = Hash.new { |hash,key| hash[key] = {} }
Array === set[:listeners] or set[:listeners] = []
load(false)
end
|
Instance Attribute Details
#after_load ⇒ Object
17
18
19
|
# File 'lib/pitchfork/configurator.rb', line 17
def after_load
@after_load
end
|
#config_file ⇒ Object
17
18
19
|
# File 'lib/pitchfork/configurator.rb', line 17
def config_file
@config_file
end
|
#set ⇒ Object
17
18
19
|
# File 'lib/pitchfork/configurator.rb', line 17
def set
@set
end
|
Instance Method Details
#[](key) ⇒ Object
130
131
132
|
# File 'lib/pitchfork/configurator.rb', line 130
def [](key) set[key]
end
|
#after_mold_fork(*args, &block) ⇒ Object
151
152
153
|
# File 'lib/pitchfork/configurator.rb', line 151
def after_mold_fork(*args, &block)
set_hook(:after_mold_fork, block_given? ? block : args[0])
end
|
#after_monitor_ready(*args, &block) ⇒ Object
159
160
161
|
# File 'lib/pitchfork/configurator.rb', line 159
def after_monitor_ready(*args, &block)
set_hook(:after_monitor_ready, block_given? ? block : args[0], 1)
end
|
#after_request_complete(*args, &block) ⇒ Object
179
180
181
|
# File 'lib/pitchfork/configurator.rb', line 179
def after_request_complete(*args, &block)
set_hook(:after_request_complete, block_given? ? block : args[0], 3)
end
|
#after_worker_exit(*args, &block) ⇒ Object
175
176
177
|
# File 'lib/pitchfork/configurator.rb', line 175
def after_worker_exit(*args, &block)
set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
end
|
#after_worker_fork(*args, &block) ⇒ Object
147
148
149
|
# File 'lib/pitchfork/configurator.rb', line 147
def after_worker_fork(*args, &block)
set_hook(:after_worker_fork, block_given? ? block : args[0])
end
|
#after_worker_hard_timeout(*args, &block) ⇒ Object
167
168
169
|
# File 'lib/pitchfork/configurator.rb', line 167
def after_worker_hard_timeout(*args, &block)
set_hook(:after_worker_hard_timeout, block_given? ? block : args[0], 2)
end
|
#after_worker_ready(*args, &block) ⇒ Object
155
156
157
|
# File 'lib/pitchfork/configurator.rb', line 155
def after_worker_ready(*args, &block)
set_hook(:after_worker_ready, block_given? ? block : args[0])
end
|
#after_worker_timeout(*args, &block) ⇒ Object
163
164
165
|
# File 'lib/pitchfork/configurator.rb', line 163
def after_worker_timeout(*args, &block)
set_hook(:after_worker_timeout, block_given? ? block : args[0], 3)
end
|
#before_fork(*args, &block) ⇒ Object
143
144
145
|
# File 'lib/pitchfork/configurator.rb', line 143
def before_fork(*args, &block)
set_hook(:before_fork, block_given? ? block : args[0], 1)
end
|
#before_service_worker_exit(&block) ⇒ Object
187
188
189
|
# File 'lib/pitchfork/configurator.rb', line 187
def before_service_worker_exit(&block)
set_hook(:before_service_worker_exit, block, 2)
end
|
#before_service_worker_ready(&block) ⇒ Object
183
184
185
|
# File 'lib/pitchfork/configurator.rb', line 183
def before_service_worker_ready(&block)
set_hook(:before_service_worker_ready, block, 2)
end
|
#before_worker_exit(*args, &block) ⇒ Object
171
172
173
|
# File 'lib/pitchfork/configurator.rb', line 171
def before_worker_exit(*args, &block)
set_hook(:before_worker_exit, block_given? ? block : args[0], 2)
end
|
#check_client_connection(bool) ⇒ Object
261
262
263
|
# File 'lib/pitchfork/configurator.rb', line 261
def check_client_connection(bool)
set_bool(:check_client_connection, bool)
end
|
#client_body_buffer_size(bytes) ⇒ Object
257
258
259
|
# File 'lib/pitchfork/configurator.rb', line 257
def client_body_buffer_size(bytes)
set_int(:client_body_buffer_size, bytes, 0)
end
|
#commit!(server, options = {}) ⇒ Object
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# File 'lib/pitchfork/configurator.rb', line 110
def commit!(server, options = {}) skip = options[:skip] || []
if ready_pipe = RACKUP.delete(:ready_pipe)
server.ready_pipe = ready_pipe
end
if set[:check_client_connection]
set[:listeners].each do |address|
if set[:listener_opts][address][:tcp_nopush] == true
raise ArgumentError,
"check_client_connection is incompatible with tcp_nopush:true"
end
end
end
set.each do |key, value|
value == :unset and next
skip.include?(key) and next
server.__send__("#{key}=", value)
end
end
|
#early_hints(bool) ⇒ Object
218
219
220
|
# File 'lib/pitchfork/configurator.rb', line 218
def early_hints(bool)
set_bool(:early_hints, bool)
end
|
#expand_addr(address) ⇒ Object
expands “unix:path/to/foo” to a socket relative to the current path expands pathnames of sockets if relative to “~” or “~username” expands “*:port and ”:port“ to ”0.0.0.0:port“
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
# File 'lib/pitchfork/configurator.rb', line 284
def expand_addr(address) return "0.0.0.0:#{address}" if Integer === address
return address unless String === address
case address
when %r{\Aunix:(.*)\z}
File.expand_path($1)
when %r{\A~}
File.expand_path(address)
when %r{\A(?:\*:)?(\d+)\z}
"0.0.0.0:#$1"
when %r{\A\[([a-fA-F0-9:]+)\]\z}, %r/\A((?:\d+\.){3}\d+)\z/
canonicalize_tcp($1, 80)
when %r{\A\[([a-fA-F0-9:]+)\]:(\d+)\z}, %r{\A(.*):(\d+)\z}
canonicalize_tcp($1, $2.to_i)
else
address
end
end
|
#listen(address, options = {}) ⇒ Object
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
# File 'lib/pitchfork/configurator.rb', line 230
def listen(address, options = {})
address = expand_addr(address)
if String === address
[ :umask, :backlog, :sndbuf, :rcvbuf, :tries, :queues, :queues_per_worker].each do |key|
value = options[key] or next
Integer === value or
raise ArgumentError, "not an integer: #{key}=#{value.inspect}"
end
[ :tcp_nodelay, :tcp_nopush, :ipv6only, :reuseport ].each do |key|
(value = options[key]).nil? and next
TrueClass === value || FalseClass === value or
raise ArgumentError, "not boolean: #{key}=#{value.inspect}"
end
unless (value = options[:delay]).nil?
Numeric === value or
raise ArgumentError, "not numeric: delay=#{value.inspect}"
end
set[:listener_opts][address].merge!(options)
end
set[:listeners] << address
end
|
#listeners(addresses) ⇒ Object
sets listeners to the given addresses
, replacing or augmenting the current set.
224
225
226
227
228
|
# File 'lib/pitchfork/configurator.rb', line 224
def listeners(addresses) Array === addresses or addresses = Array(addresses)
addresses.map! { |addr| expand_addr(addr) }
set[:listeners] = addresses
end
|
#load(merge_defaults = true) ⇒ Object
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/pitchfork/configurator.rb', line 98
def load(merge_defaults = true) if merge_defaults && @use_defaults
set.merge!(DEFAULTS) if @use_defaults
end
instance_eval(File.read(config_file), config_file) if config_file
parse_rackup_file
RACKUP[:set_listener] and
set[:listeners] << "#{RACKUP[:host]}:#{RACKUP[:port]}"
end
|
#logger(obj) ⇒ Object
134
135
136
137
138
139
140
141
|
# File 'lib/pitchfork/configurator.rb', line 134
def logger(obj)
%w(debug info warn error fatal).each do |m|
obj.respond_to?(m) and next
raise ArgumentError, "logger=#{obj} does not respond to method=#{m}"
end
set[:logger] = obj
end
|
#refork_after(limits) ⇒ Object
Defines the number of requests per-worker after which a new generation should be spawned.
false
can be used to mark a final generation, otherwise the last request count is re-used indefinitely.
example: . refork_after [50, 100, 1000] . refork_after [50, 100, 1000, false]
Note that reforking is only available on Linux. Other Unix-like systems don’t have this capability.
277
278
279
|
# File 'lib/pitchfork/configurator.rb', line 277
def refork_after(limits)
set[:refork_condition] = ReforkCondition::RequestsCount.new(limits)
end
|
253
254
255
|
# File 'lib/pitchfork/configurator.rb', line 253
def rewindable_input(bool)
set_bool(:rewindable_input, bool)
end
|
#spawn_timeout(seconds) ⇒ Object
210
211
212
|
# File 'lib/pitchfork/configurator.rb', line 210
def spawn_timeout(seconds)
set_int(:spawn_timeout, seconds, 1)
end
|
#timeout(seconds, cleanup: 2) ⇒ Object
191
192
193
194
195
|
# File 'lib/pitchfork/configurator.rb', line 191
def timeout(seconds, cleanup: 2)
soft_timeout = set_int(:soft_timeout, seconds, 3)
cleanup_timeout = set_int(:cleanup_timeout, cleanup, 2)
set_int(:timeout, soft_timeout + cleanup_timeout, 5)
end
|
#timeout_signal(*args, &block) ⇒ Object
197
198
199
200
201
202
203
204
205
206
207
208
|
# File 'lib/pitchfork/configurator.rb', line 197
def timeout_signal(*args, &block)
if block_given?
set_hook(:timeout_signal, block, 1)
elsif args.first.respond_to?(:call)
set_hook(:timeout_signal, args.first, 1)
elsif args.first.is_a?(Symbol)
signal = args.first
set_hook(:timeout_signal, ->(_pid) { signal }, 1)
else
raise ArgumentError, "timeout_signal must be a symbol or a proc"
end
end
|
#worker_processes(nr) ⇒ Object
214
215
216
|
# File 'lib/pitchfork/configurator.rb', line 214
def worker_processes(nr)
set_int(:worker_processes, nr, 1)
end
|