Skip to content

Instantly share code, notes, and snippets.

@arika arika/.spring.rb
Last active Aug 3, 2018

Embed
What would you like to do?
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
You can’t perform that action at this time.