-
Notifications
You must be signed in to change notification settings - Fork 368
Expand file tree
/
Copy pathpuma_runner.rb
More file actions
96 lines (80 loc) · 3.56 KB
/
puma_runner.rb
File metadata and controls
96 lines (80 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
require 'puma'
require 'puma/configuration'
require 'puma/events'
require 'cloud_controller/logs/steno_io'
require 'cloud_controller/execution_context'
module VCAP::CloudController
class PumaRunner
def initialize(config, app, logger, periodic_updater, request_logs)
@periodic_updater = periodic_updater
@logger = logger
ENV['WEB_CONCURRENCY'] = 'auto' if config.get(:puma, :automatic_worker_count)
puma_config = Puma::Configuration.new do |conf|
if config.get(:nginx, :use_nginx)
if config.get(:nginx, :instance_socket).nil? || config.get(:nginx, :instance_socket).empty?
conf.bind 'tcp://0.0.0.0:3000'
else
conf.bind "unix://#{config.get(:nginx, :instance_socket)}"
end
else
conf.bind "tcp://0.0.0.0:#{config.get(:external_port)}"
end
# Keep Puma 6 defaults (25/20s) to avoid surprises with Nginx. Puma 7 defaults may be revisited for performance later.
conf.max_keep_alive(25)
conf.persistent_timeout(20)
conf.workers(config.get(:puma, :workers) || 1) unless config.get(:puma, :automatic_worker_count)
num_threads = config.get(:puma, :max_threads) || 1
conf.threads(num_threads, num_threads)
# In theory there shouldn't be any open connections when shutting down Puma as they have either been gracefully
# drained or forcefully terminated (after cc.nginx_drain_timeout) by Nginx. Puma has some built-in (i.e. not
# changeable) timeouts as well as some configurable timeouts.
# Reduce the worker shutdown timeout to 15 seconds (default is 30).
conf.worker_shutdown_timeout(15)
# Reduce the thread shutdown timeout to 10 seconds (4 [force_shutdown_after] + 5 [SHUTDOWN_GRACE_TIME] + 1)
conf.force_shutdown_after(4)
# replace PidFormatter as we already have the pid in the Steno log record
formatter = Puma::LogWriter::DefaultFormatter.new
conf.log_formatter { |str| formatter.call(str) }
conf.app app
conf.before_fork do
Sequel::Model.db.disconnect
end
conf.before_worker_boot { ExecutionContext::API_PUMA_WORKER.set_process_type_env }
conf.before_worker_shutdown { request_logs.log_incomplete_requests if request_logs }
end
log_writer = Puma::LogWriter.new(StenoIO.new(logger, :info), StenoIO.new(logger, :error))
events = Puma::Events.new
events.after_booted { @periodic_updater.setup_updates }
events.after_stopped { stop_periodic_updates }
@puma_launcher = Puma::Launcher.new(puma_config, log_writer:, events:)
end
def start!
@puma_launcher.run
rescue StandardError => e
@logger.error "Encountered error: #{e}\n#{e.backtrace&.join("\n")}"
raise e
end
private
def stop_periodic_updates
return unless @periodic_updater
if @periodic_updater.stop_updates
@logger.info('Successfully stopped periodic updates in after_stopped')
else
@logger.warn('Failed to stop all periodic update tasks in after_stopped')
end
rescue ThreadError
at_exit do
if @periodic_updater.stop_updates
@logger.info('Successfully stopped periodic updates in at_exit')
else
@logger.warn('Failed to stop all periodic update tasks in at_exit')
end
end
rescue StandardError => e
@logger.error("Failed to stop periodic updates: #{e}\n#{e.backtrace&.join("\n")}")
end
def prometheus_updater
CloudController::DependencyLocator.instance.prometheus_updater
end
end
end