Control C Handling
There are a couple of options in the signal
package for handling interrupts.
- Have the signal written to a channel.
- Have the signal cancel a context.
I’ve used the second method for handling control-c. The context returned is
from context.WithCancel(..)
which is a common (standard) way to notify child
processing that it can stop. The context has a channel built in that is closed
when the context is canceled. Anyone waiting on that channel will block until
the channel is closed. The context can be read by multiple goroutines. You can
also put the channel in a select{} clause for more flexibility.
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
This context will then be used by the listener to close its connection
go func() {
<-ctx.Done()
listener.Close()
}()
And used by the web server to have it shutdown.
go func() {
<-ctx.Done()
...
if err := srv.Shutdown(timeout); err != nil {...}
...
}()