Skip to content

Instantly share code, notes, and snippets.

@arika
Last active August 3, 2018 04:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arika/617fd8d40b12b8bf3bbef73e40f02260 to your computer and use it in GitHub Desktop.
Save arika/617fd8d40b12b8bf3bbef73e40f02260 to your computer and use it in GitHub Desktop.
auto stop spring server
module DotSpringRb
MONITOR_INTERVAL = 10*60
SERVER_KEEP_PERIOD = 30*60
module_function
def env
@env ||= Spring::Env.new
end
def start_idle_monitor
Thread.new do
alive_at = Time.now
loop do
sleep MONITOR_INTERVAL
now = Time.now
current_worker_pids = worker_pids(env.pid)
env.log "[idle_monitor] worker_pids = #{current_worker_pids.join(',')}"
if current_worker_pids.empty?
break if alive_at + SERVER_KEEP_PERIOD < now
else
alive_at = now
end
end
cleanup_server
end
end
def cleanup_server
env.log "[idle_monitor] try to stop server"
execute_spring :stop
execute_spring :status
end
def execute_spring(command)
require 'open3'
cmd = "spring #{command}"
env.log "[idle_monitor] execute: #{cmd}"
out, err, status = Open3.capture3(cmd)
env.log "[idle_monitor] status: #{status.exitstatus}"
out.each_line {|line| env.log "[idle_monitor] stdout: #{line}" }
err.each_line {|line| env.log "[idle_monitor] stderr: #{line}" }
end
def worker_pids(server_pid)
app_manager_pids = child_pids([server_pid])
child_pids(app_manager_pids, exclude: %r{/.*?/fsevent_watch })
end
def child_pids(parent_pids, exclude: nil)
return [] if parent_pids.empty?
`ps ax -o ppid,pid,command`
.scan(/^\s*(?:#{parent_pids.join('|')})\s+(\d+)\s+(.*)/)
.map {|pid, command| exclude && exclude =~ command ? nil : pid }
.compact
end
def process_type
return :server unless env.server_running?
return :app_manager if env.pid == Process.ppid
:worker
end
def display_process_info
# p [process_type, $$, $0, env.pid]
end
end
DotSpringRb.display_process_info
Spring.after_fork do
DotSpringRb.display_process_info
end
DotSpringRb.start_idle_monitor if DotSpringRb.process_type == :server
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment