This article explain "How to implement a signal handler in Go".
Also, I introduce a small library I made.
Introduction
This implement is assumed as follows.
- Subscriber in PubSub
- Show shutdown message
- etc...
If knowing how to implement signal handlers, you can create programs with diversity in Go.
How to implement
The main points are as follows for implement.
- Catch signal
- Wait for caught signal
Catch signal
First, let's write program for catch signal.
Use "chan" for catch signal.
package main
import (
"os"
"os/signal"
)
func main() {
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt)
<-signalCh
}
This program is so simple.
Create os.Signal channel, and Receive os.Interrupt(= syscall.SIGINT) notify used signalCh.
As a side note, <-signalCh
is wait for signalCh receive interrupt signal.
Wait for caught signal in goroutine
Since you can not do anything until you receive a signal, improve this program so that you can receive a signal with goroutine.
package main
import (
"os"
"os/signal"
)
func main() {
doneCh := make(chan struct{})
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, os.Interrupt)
go receive(signalCh, doneCh)
<-doneCh
}
func receive(signalCh chan os.Signal, doneCh chan struct{}) {
for {
select {
// Example. Process to receive a message
// case msg := <-receiveMessage():
case <-signalCh:
doneCh <- struct{}{}
}
}
}
Execute the receive function using goroutine.
The receive function uses for and select and continues to move until you catch the signal.
When catching a signal, it sends an empty structure to doneCh and tells you that you caught the signal.
As an example, in the case of PubSub, we write a process to catch the message with the receive function.
Investigation
I investigated whether there is a library that can easily implement signal processing.
I found this library.
https://github.com/vrecan/death
However, in this library, it was troublesome to generate structure objects and create fixed structure methods.
Create
Therefore, I made a library called TebataοΌζζοΌ.
https://github.com/syossan27/tebata
Tebata can easily and flexibly create signal handler.
func main() {
doneCh := make(chan struct{})
t := tebata.New(os.Interrupt)
t.Receive(func(ch chan struct{}){
fmt.Println("Catch signal!")
ch <- struct{}{}
}, doneCh)
<-doneCh
}
Specify the signal you want to catch in the argument of New function.
Then, specify the function and argument you want to execute as the argument of the Receive function.
Only this.
If you want to implement a signal handler please try this library.
Top comments (0)