Na configuração do puma:
workers 8
pidfile "/app_pids_path/puma.pid" # Cluster PID
on_worker_boot do |wid|
File.open("/app_pids_path/puma/worker_#{wid}.pid", "w"){|f| f.puts Process.pid }
end
O Puma permite gerar trabalhadores ausentes enviando o sinal SIGCHLD para o processo de cluster.
Além disso, sinais úteis: TTIN – gera mais um trabalhador, TTOU – mata o último trabalhador.
Pequeno script de shell respawn_worker
(não se esqueça de torná-lo executável):
Uso:respawn_worker WORKER_SERIAL_NUMBER
#!/usr/bin/env bash
pid_file="/app_pids_path/puma.pid" # Cluster PID
pid_dir=`dirname $pid_file`
[[ -e $pid_file ]] || exit 1
[[ -z "$1" ]] && exit 1
kill `cat ${pid_dir}/puma/worker_$1.pid`
kill -s SIGCHLD `cat $pid_file`
E, finalmente, monit config script:
check process my_app_puma_worker_0
with pidfile /app_pids_path/puma/worker_0.pid
if totalmem is greater than 300 MB for 2 cycles then exec "/script_dir/respawn_worker 0"
check process my_app_puma_worker_1
with pidfile /app_pids_path/puma/worker_1.pid
if totalmem is greater than 320 MB for 2 cycles then exec "/script_dir/respawn_worker 1"
check process my_app_puma_worker_2
with pidfile /app_pids_path/puma/worker_2.pid
if totalmem is greater than 340 MB for 2 cycles then exec "/script_dir/respawn_worker 2"
# ... and for each worker