Created
July 28, 2022 04:56
-
-
Save keithrbennett/d95653af91184b9eb9b35d26f8b9b2e8 to your computer and use it in GitHub Desktop.
Illustrates the use of 'trap' in Ruby for crude interprocess communication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Author: @keithrbennett (Github) | |
# Illustrates how to respond to Unix signals in a Ruby program, using SIGUSR1 and SIGUSR2 | |
# for user-defined signals, and SIGINT for trapping Ctrl-C. | |
require 'awesome_print' | |
require 'json' | |
require 'yaml' | |
$stderr.puts <<~GREETING | |
Pid is #{Process.pid}. | |
Standard output is a #{$stdout.tty? ? 'tty' : 'block'} device. | |
You can send signals SIGUSR1 and SIGUSR2 (e.g. via `kill`) to poke this program | |
to output its stats in human readable or YAML forms: | |
kill -SIGUSR1 #{Process.pid} # Human readable (Awesome/Amazing Print) | |
kill -SIGUSR2 #{Process.pid} # YAML | |
...and to terminate the program, outputting the final data observation: | |
kill -SIGINT #{Process.pid} # Terminate | |
GREETING | |
SystemInfo = Struct.new(:pid, :uptime, :res_memory_mb) | |
# See this great article about monotonic time: https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/ | |
def monotonic_time_now | |
Process.clock_gettime(Process::CLOCK_MONOTONIC) | |
end | |
START_TIME = monotonic_time_now | |
def monotonic_uptime | |
monotonic_time_now - START_TIME | |
end | |
def resident_memory_in_mb | |
# -o = format with the following data | |
# rss = resident memory set size, in ? | |
# h = omit the header ("RSS") | |
command = "ps -o rss h #{Process.pid}" | |
output = `#{command}` | |
kb = output.strip.to_i | |
(kb / 1024.0).round(0) | |
end | |
def system_info | |
SystemInfo.new(Process.pid, monotonic_uptime.round(2), resident_memory_in_mb) | |
end | |
def print_system_info | |
ap system_info.to_h | |
end | |
Signal.trap('USR1') { print_system_info } | |
Signal.trap('USR2') { puts system_info.to_h.to_yaml } | |
Signal.trap('INT') do | |
puts "\nEnding program, final stats are:" | |
print_system_info | |
exit | |
end | |
# See https://dsa.cs.tsinghua.edu.cn/oj/static/unix_signal.html for signal values. | |
#Signal.trap(30) { puts 30 } | |
#Signal.trap(10) { puts 10 } | |
memory_black_hole = [] | |
loop do | |
sleep 0.5 | |
memory_black_hole << Array.new(100_000) { Time.now } | |
#puts "Time count: #{ObjectSpace.each_object(Time).count}" | |
$stdout.flush | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment