Signals in Kotlin

Here’s the translation of the Go code to Kotlin, with explanations adapted for Kotlin and formatted in Markdown suitable for Hugo:

Our first program demonstrates how to handle signals in Kotlin. Here’s the full source code:

import kotlinx.coroutines.*
import kotlin.system.exitProcess
import kotlin.concurrent.thread
import java.util.concurrent.CountDownLatch
import sun.misc.Signal

fun main() = runBlocking {
    // Kotlin doesn't have a direct equivalent to Go's signal.Notify,
    // so we'll use Java's sun.misc.Signal class for signal handling
    val sigs = Channel<String>(1)

    // Register handlers for SIGINT and SIGTERM
    listOf("INT", "TERM").forEach { signalName ->
        Signal.handle(Signal(signalName)) { signal ->
            runBlocking {
                sigs.send(signal.name)
            }
        }
    }

    // We'll use a CountDownLatch to demonstrate a more realistic
    // scenario of graceful shutdown
    val done = CountDownLatch(1)

    // This coroutine executes a blocking receive for signals.
    // When it gets one, it'll print it out and then notify
    // the program that it can finish.
    launch {
        val sig = sigs.receive()
        println()
        println(sig)
        done.countDown()
    }

    // The program will wait here until it gets the expected signal
    // (as indicated by the coroutine above counting down the latch)
    // and then exit.
    println("awaiting signal")
    done.await()
    println("exiting")
    exitProcess(0)
}

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 INT and then exit.

$ kotlinc -cp .:kotlinx-coroutines-core-1.5.2.jar SignalHandler.kt -include-runtime -d SignalHandler.jar
$ java -jar SignalHandler.jar
awaiting signal
^C
INT
exiting

Note that signal handling in Kotlin is not as straightforward as in Go, and we had to use Java’s sun.misc.Signal class, which is not a standard API and may not be available on all Java implementations. In a production environment, you might want to consider using a more robust solution for signal handling.

Also, remember that Kotlin coroutines are used here as an analog to Go’s goroutines, providing a way to handle concurrency in a more idiomatic Kotlin style.