yan's blog

Go Signal

dumy code example for golang handle graceful shutdown.

package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"
)

type task struct {
	// receive user quit event, then do clean up
	quitChan chan struct{}
}

func newTask() *task {
	return &task{
		quitChan: make(chan struct{}),
	}
}

func (t *task) run() {
	for {
		select {
		case <-t.quitChan:
			fmt.Println("user want to quit, clean up now")
			time.Sleep(time.Second * 1)
			fmt.Println("clean up success, now main goroutine can quit")
			// don't forget this return
			return
		case <-time.NewTicker(time.Second * 2).C:
			fmt.Println("do task...")
		}
	}
}

func main() {
	sigs := make(chan os.Signal, 1)

	// example:
	// ctrl + C is SIGINT
	// using kill command is SIGTERM
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	t := newTask()

	go func() {
		quitSig := <-sigs
		fmt.Printf("get quit signal: %v\n", quitSig)
		fmt.Println("let's stop our running task")
		// send signal to notify task to clean up
		t.quitChan <- struct{}{}
	}()

	t.run()
}