Skip to content

Commit

Permalink
add test for systemd plugin and tweak message fetch logic
Browse files Browse the repository at this point in the history
  • Loading branch information
QWYNG committed Jan 17, 2023
1 parent 5e521bc commit 338ef29
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
50 changes: 18 additions & 32 deletions lib/puma/plugin/systemd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,24 @@
# 4. periodically set the status
Puma::Plugin.create do
def start(launcher)
begin
require 'sd_notify'
rescue LoadError
launcher.log_writer.log "Systemd integration failed. It looks like you're trying to use systemd notify but don't have sd_notify gem installed"
return
end
require_relative '../sd_notify'

launcher.log_writer.log "* Enabling systemd notification integration"

# hook_events
launcher.events.on_booted { SdNotify.ready }
launcher.events.on_stopped { SdNotify.stopping }
launcher.events.on_restart { SdNotify.reloading }
launcher.events.on_booted { Puma::SdNotify.ready }
launcher.events.on_stopped { Puma::SdNotify.stopping }
launcher.events.on_restart { Puma::SdNotify.reloading }

# start watchdog
if SdNotify.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
SdNotify.watchdog
Puma::SdNotify.watchdog
end
end
end
Expand All @@ -45,17 +40,20 @@ def start(launcher)
loop do
sleep sleep_time
# TODO: error handling?
SdNotify.status(instance.status)
Puma::SdNotify.status(instance.status)
end
end
end

def status
common = "workers: #{running}/#{max_threads} threads, #{pool_capacity} available, #{backlog} backlog"
if clustered?
"Puma #{Puma::Const::VERSION} cluster: #{booted_workers}/#{workers} #{common}"
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}: #{common}"
"Puma #{Puma::Const::VERSION}: worker: #{common_message(stats)}"
end
end

Expand All @@ -75,30 +73,18 @@ def stats
end

def clustered?
stats.has_key?('workers')
stats.has_key?(:workers)
end

def workers
stats.fetch('workers', 1)
stats.fetch(:workers, 1)
end

def booted_workers
stats.fetch('booted_workers', 1)
end

def running
stats['running']
end

def backlog
stats['backlog']
end

def pool_capacity
stats['pool_capacity']
stats.fetch(:booted_workers, 1)
end

def max_threads
stats['max_threads']
def common_message(stats)
"{ #{stats[:running]}/#{stats[:max_threads]} threads, #{stats[:pool_capacity]} available, #{stats[:backlog]} backlog }"
end
end
27 changes: 24 additions & 3 deletions test/test_integration_systemd.rb → test/test_plugin_systemd.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative "helper"
require_relative "helpers/integration"

class TestIntegrationSystemd < TestIntegration
class TestPluginSystemd < TestIntegration
def setup
skip "Skipped because Systemd support is linux-only" if windows? || osx?
skip_unless :unix
Expand Down Expand Up @@ -55,6 +55,27 @@ def test_systemd_watchdog
assert_match(socket_message, "STOPPING=1")
end

def test_systemd_notify
cli_server "test/rackup/hello.ru"
assert_equal(socket_message, "READY=1")

assert_equal(socket_message(70),
"STATUS=Puma #{Puma::Const::VERSION}: worker: { 0/5 threads, 5 available, 0 backlog }")

stop_server
assert_match(socket_message, "STOPPING=1")
end

def test_systemd_cluster_notify
cli_server "-w 2 -q test/rackup/hello.ru"
assert_equal(socket_message, "READY=1")
assert_equal(socket_message(130),
"STATUS=Puma #{Puma::Const::VERSION}: cluster: 2/2, worker_status: [{ 0/5 threads, 5 available, 0 backlog },{ 0/5 threads, 5 available, 0 backlog }]")

stop_server
assert_match(socket_message, "STOPPING=1")
end

private

def assert_restarts_with_systemd(signal, workers: 2)
Expand All @@ -75,7 +96,7 @@ def assert_restarts_with_systemd(signal, workers: 2)
assert_equal socket_message, 'STOPPING=1'
end

def socket_message
@socket.recvfrom(15)[0]
def socket_message(len = 15)
@socket.recvfrom(len)[0]
end
end

0 comments on commit 338ef29

Please sign in to comment.