Signals in Groovy

Here’s the translation of the Go code example to Groovy, formatted in Markdown suitable for Hugo:

Our program demonstrates how to handle signals in Groovy. It shows how to gracefully shutdown a program when it receives a SIGTERM or stop processing input if it receives a SIGINT. Here’s how to handle signals in Groovy using a shutdown hook.

import sun.misc.Signal
import sun.misc.SignalHandler

// We'll use a volatile boolean to indicate when the program should exit
@groovy.transform.Field
volatile boolean shouldExit = false

// This closure will be executed when a signal is received
def signalHandler = { sig ->
    println()
    println(sig)
    shouldExit = true
}

// Register the signal handler for SIGINT and SIGTERM
Signal.handle(new Signal("INT"), signalHandler as SignalHandler)
Signal.handle(new Signal("TERM"), signalHandler as SignalHandler)

// Main program logic
println("awaiting signal")

// Simulate some work
while (!shouldExit) {
    Thread.sleep(1000)
}

println("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 interrupt and then exit.

$ groovy signals.groovy
awaiting signal
^C
SIGINT
exiting

In this Groovy version:

  1. We use the sun.misc.Signal and sun.misc.SignalHandler classes to handle signals. Note that these are Sun-specific classes and may not be available in all Java implementations.

  2. We define a volatile boolean shouldExit to indicate when the program should exit. This is used to communicate between the signal handling thread and the main thread.

  3. The signalHandler closure is defined to handle the received signals. It prints the signal and sets shouldExit to true.

  4. We register this handler for both SIGINT and SIGTERM signals using Signal.handle().

  5. The main program logic is a simple loop that continues until shouldExit is set to true.

  6. When a signal is received, the handler sets shouldExit to true, causing the main loop to exit and the program to terminate.

This approach provides a way to gracefully handle signals in Groovy, allowing for cleanup operations or other necessary actions before the program exits.