Signals in Ruby

Here’s the translation of the Go code to Ruby, with explanations in Markdown format suitable for Hugo:

Our program demonstrates how to handle Unix signals in Ruby. For example, we might want a server to gracefully shutdown when it receives a SIGTERM, or a command-line tool to stop processing input if it receives a SIGINT. Here’s how to handle signals in Ruby.

require 'signal'

# Ruby signal handling works by registering callbacks for specific signals.
# We'll create a variable to indicate when the program should exit.
done = false

# Signal.trap registers a callback for the specified signal.
# Here we're handling SIGINT (Ctrl+C) and SIGTERM.
Signal.trap("INT") do
  puts
  puts "SIGINT"
  done = true
end

Signal.trap("TERM") do
  puts
  puts "SIGTERM"
  done = true
end

# This represents the main logic of our program.
# It will continue running until a signal is received.
puts "awaiting signal"
until done
  sleep 1
end

puts "exiting"

When we run this program it will block waiting for a signal. By typing ctrl-C (which the terminal shows as ^C) we can send a SIGINT signal, causing the program to print SIGINT and then exit.

$ ruby signals.rb
awaiting signal
^C
SIGINT
exiting

In this Ruby version:

  1. We use the Signal module to handle signals.
  2. Instead of channels, we use a boolean variable done to indicate when the program should exit.
  3. We register signal handlers using Signal.trap. These handlers set done to true when a signal is received.
  4. The main program loop uses until done to wait for a signal, simulating the blocking behavior of the original Go program.
  5. We use sleep 1 in the loop to prevent the program from consuming too much CPU while waiting.

This approach provides similar functionality to the Go version, allowing graceful handling of signals in a Ruby program.