-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathsystemd.rb
More file actions
90 lines (72 loc) · 2.21 KB
/
systemd.rb
File metadata and controls
90 lines (72 loc) · 2.21 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
# frozen_string_literal: true
require_relative '../plugin'
# Puma's systemd integration allows Puma to inform systemd:
# 1. when it has successfully started
# 2. when it is starting shutdown
# 3. periodically for a liveness check with a watchdog thread
# 4. periodically set the status
Puma::Plugin.create do
def start(launcher)
require_relative '../sd_notify'
launcher.log_writer.log "* Enabling systemd notification integration"
# hook_events
launcher.events.on_booted { Puma::SdNotify.ready }
launcher.events.on_stopped { Puma::SdNotify.stopping }
launcher.events.on_restart { Puma::SdNotify.reloading }
# start watchdog
if Puma::SdNotify.watchdog?
ping_f = watchdog_sleep_time
in_background do
launcher.log_writer.log "Pinging systemd watchdog every #{ping_f.round(1)} sec"
loop do
sleep ping_f
Puma::SdNotify.watchdog
end
end
end
# start status loop
instance = self
sleep_time = 1.0
in_background do
launcher.log_writer.log "Sending status to systemd every #{sleep_time.round(1)} sec"
loop do
sleep sleep_time
# TODO: error handling?
Puma::SdNotify.status(instance.status)
end
end
end
def status
if clustered?
messages = stats[:worker_status].map do |worker|
common_message(worker[:last_status])
end.join(',')
"Puma #{Puma::Const::VERSION}: cluster: #{booted_workers}/#{workers}, worker_status: [#{messages}]"
else
"Puma #{Puma::Const::VERSION}: worker: #{common_message(stats)}"
end
end
private
def watchdog_sleep_time
usec = Integer(ENV["WATCHDOG_USEC"])
sec_f = usec / 1_000_000.0
# "It is recommended that a daemon sends a keep-alive notification message
# to the service manager every half of the time returned here."
sec_f / 2
end
def stats
Puma.stats_hash
end
def clustered?
stats.has_key?(:workers)
end
def workers
stats.fetch(:workers, 1)
end
def booted_workers
stats.fetch(:booted_workers, 1)
end
def common_message(stats)
"{ #{stats[:running]}/#{stats[:max_threads]} threads, #{stats[:pool_capacity]} available, #{stats[:backlog]} backlog }"
end
end