1
Fork 0

Improvements

This commit is contained in:
Jan-Lukas Else 2021-07-07 08:55:15 +02:00
parent 8953b4bd54
commit 773db8099c
1 changed files with 29 additions and 36 deletions

View File

@ -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