Handle CTRL-C (SIGINT) in Golang

A common pattern to interrupt a long-running task in a console application is to handle the CTRL-C signal using the Notify function from the signal package. You have a channel that is passed to the Notify function, which will receive a signal when a particular event occurs, such as someone pressing CTRL-C. However, there is an even more idiomatic way to cancel long-running tasks using Context, which is a common approach to canceling the entire pipeline of running tasks when making an HTTP request. This can be achieved using NotifyContext:

package main

import (
	"context"
	"log/slog"
	"os"
	"os/signal"
	"time"
)

func ticker(ctx context.Context) {
	t := time.NewTicker(500 * time.Millisecond)
	for {
		select {
		case <-ctx.Done():
			slog.Info("Context cancelled")
			return
		case v := <-t.C:
			slog.Info("Tick", "time", v)
		}
	}
}

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()
	ticker(ctx)
	slog.Info("Done")
}