Signals in Idris

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

Our first example demonstrates how to handle signals in Idris. This can be useful for gracefully shutting down a server when it receives a SIGTERM, or stopping a command-line tool from processing input when it receives a SIGINT.

module Main

import System.Signal
import System.Concurrency
import System

main : IO ()
main = do
    -- Create a channel to receive signal notifications
    sigChan <- makeChannel

    -- Register the channel to receive SIGINT and SIGTERM signals
    _ <- forkIO $ do
        registerSignalHandler [SIGINT, SIGTERM] (\sig => putChannel sigChan sig)

    -- Create a channel to signal when we're done
    doneChan <- makeChannel

    -- Start a thread to handle incoming signals
    _ <- forkIO $ do
        sig <- takeChannel sigChan
        putStrLn ""
        putStrLn $ "Received signal: " ++ show sig
        putChannel doneChan ()

    putStrLn "Awaiting signal"
    
    -- Wait for the signal handling to complete
    _ <- takeChannel doneChan
    
    putStrLn "Exiting"

In this Idris program:

  1. We create a channel sigChan to receive signal notifications.

  2. We use registerSignalHandler to register SIGINT and SIGTERM signals. When these signals are received, they’re sent to sigChan.

  3. We create another channel doneChan to coordinate between the main thread and the signal handling thread.

  4. We start a separate thread that waits for a signal on sigChan. When it receives a signal, it prints the signal and notifies the main thread via doneChan.

  5. The main thread waits on doneChan, effectively blocking until a signal is received and processed.

To run this program:

$ idris -o signals signals.idr
$ ./signals
Awaiting signal
^C
Received signal: SIGINT
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 the received signal and then exit.

Note that Idris’s approach to concurrency and signal handling is different from some other languages. It uses lightweight threads and channels for communication, which provides a safe and composable way to handle concurrent operations.