In this example we are going to catch certain signals and wait for 3 seconds before terminating looping operation.


Example


package main

import (
"log"
"os"
"os/signal"
"syscall"
"time"

"internal/app"
)

func main() {
go shutdownHandler()

app.App{Count: 100, Sleep: 300}.Run()
}

// shutdownHandler triggers application shutdown.
func shutdownHandler() {
// signChan channel is used to transmit signal notifications.
signChan := make(chan os.Signal, 1)
// Catch and relay certain signal(s) to signChan channel.
signal.Notify(signChan, os.Interrupt, syscall.SIGTERM)

// Blocking until a signal is sent over signChan channel. Progress to
// next line after signal
sig := <-signChan

log.Println("cleanup started with", sig, "signal")
time.Sleep(time.Duration(3) * time.Second)
log.Println("cleanup completed in", 3, "seconds")

os.Exit(1)
}

package app

import (
"log"
"time"
)

type App struct {
Count int
Sleep int
}

func (a App) Run() {
for i := 1; i < a.Count; i++ {
log.Println(i, "- sleeping", a.Sleep, "milliseconds")

time.Sleep(time.Duration(a.Sleep) * time.Millisecond)
}
}

Test


2020/03/16 21:47:25 1 - sleeping 300 milliseconds
2020/03/16 21:47:25 2 - sleeping 300 milliseconds
2020/03/16 21:47:25 3 - sleeping 300 milliseconds
2020/03/16 21:47:26 4 - sleeping 300 milliseconds
2020/03/16 21:47:26 5 - sleeping 300 milliseconds
2020/03/16 21:47:26 6 - sleeping 300 milliseconds
^C
2020/03/16 21:47:26 cleanup started with interrupt signal
2020/03/16 21:47:26 7 - sleeping 300 milliseconds
2020/03/16 21:47:27 8 - sleeping 300 milliseconds
2020/03/16 21:47:27 9 - sleeping 300 milliseconds
2020/03/16 21:47:27 10 - sleeping 300 milliseconds
2020/03/16 21:47:28 11 - sleeping 300 milliseconds
2020/03/16 21:47:28 12 - sleeping 300 milliseconds
2020/03/16 21:47:28 13 - sleeping 300 milliseconds
2020/03/16 21:47:29 14 - sleeping 300 milliseconds
2020/03/16 21:47:29 15 - sleeping 300 milliseconds
2020/03/16 21:47:29 16 - sleeping 300 milliseconds
2020/03/16 21:47:29 cleanup completed in 3 seconds
exit status 1