Improvements
This commit is contained in:
parent
8953b4bd54
commit
773db8099c
65
shutdown.go
65
shutdown.go
|
@ -15,7 +15,7 @@ import (
|
||||||
// log.Println("Shutting down")
|
// log.Println("Shutting down")
|
||||||
// })
|
// })
|
||||||
type Shutdowner struct {
|
type Shutdowner struct {
|
||||||
initialized bool
|
initializer sync.Once
|
||||||
shutdown bool
|
shutdown bool
|
||||||
quit chan os.Signal
|
quit chan os.Signal
|
||||||
funcs []ShutdownFunc
|
funcs []ShutdownFunc
|
||||||
|
@ -29,49 +29,42 @@ type ShutdownFunc func()
|
||||||
|
|
||||||
// Internal method
|
// Internal method
|
||||||
func (f ShutdownFunc) execute(c context.Context) {
|
func (f ShutdownFunc) execute(c context.Context) {
|
||||||
done := false
|
done := make(chan interface{})
|
||||||
// Execute ShutdownFunc in goroutine and set done = true
|
// Execute ShutdownFunc in goroutine and close channel when finished
|
||||||
go func() {
|
go func() {
|
||||||
f()
|
f()
|
||||||
done = true
|
close(done)
|
||||||
}()
|
}()
|
||||||
for {
|
// Check if context canceled or ShutdownFunc finished
|
||||||
// Check if context canceled or ShutdownFunc finished
|
select {
|
||||||
select {
|
case <-c.Done():
|
||||||
case <-c.Done():
|
// Context canceled, return
|
||||||
// Context canceled, return
|
return
|
||||||
return
|
case <-done:
|
||||||
default:
|
// ShutdownFunc finished, return
|
||||||
if done {
|
return
|
||||||
// ShutdownFunc finished, return
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Otherwise continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal method
|
// Internal method
|
||||||
func (s *Shutdowner) init() {
|
func (s *Shutdowner) init() {
|
||||||
// Check if already initialized
|
s.initializer.Do(func() {
|
||||||
if s.initialized {
|
s.mutex.Lock()
|
||||||
return
|
defer s.mutex.Unlock()
|
||||||
}
|
// Initialize cancel context and signal channel
|
||||||
// Initialize cancel context and signal channel
|
s.cancelContext, s.cancelFunc = context.WithCancel(context.Background())
|
||||||
s.cancelContext, s.cancelFunc = context.WithCancel(context.Background())
|
s.quit = make(chan os.Signal, 2)
|
||||||
s.quit = make(chan os.Signal, 2)
|
signal.Notify(s.quit,
|
||||||
signal.Notify(s.quit,
|
os.Interrupt,
|
||||||
os.Interrupt,
|
syscall.SIGINT,
|
||||||
syscall.SIGINT,
|
syscall.SIGTERM, // e.g. Docker stop
|
||||||
syscall.SIGTERM, // e.g. Docker stop
|
)
|
||||||
)
|
go func() {
|
||||||
go func() {
|
for range s.quit {
|
||||||
for range s.quit {
|
s.Shutdown()
|
||||||
s.Shutdown()
|
}
|
||||||
}
|
}()
|
||||||
}()
|
})
|
||||||
// Finished
|
|
||||||
s.initialized = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a func, that should be called with s.Shutdown() or when receiving a shutdown signal
|
// Add a func, that should be called with s.Shutdown() or when receiving a shutdown signal
|
||||||
|
|
Loading…
Reference in New Issue