Last active
December 17, 2015 06:48
-
-
Save arikfr/5567783 to your computer and use it in GitHub Desktop.
Safe shutdown in Go.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"shutdown" | |
) | |
func main() { | |
ch := shutdown.Add("test") | |
ch2 := shutdown.Add("test2") | |
go func() { | |
for { | |
select { | |
case <-ch2: | |
log.Printf("Received the signal") | |
shutdown.Done("test2") | |
case <-ch: | |
log.Printf("Received the signal") | |
shutdown.Done("test") | |
} | |
} | |
}() | |
shutdown.Shutdown(1000) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package shutdown | |
import ( | |
"log" | |
"time" | |
) | |
var waitingList map[string]chan bool | |
var waitCh chan string | |
func init() { | |
waitingList = make(map[string]chan bool) | |
waitCh = make(chan string) | |
} | |
func Add(name string) chan bool { | |
if ch, ok := waitingList[name]; ok { | |
return ch | |
} | |
log.Printf("Shutdown: registering <%s>.", name) | |
waitingList[name] = make(chan bool) | |
return waitingList[name] | |
} | |
func Done(name string) { | |
log.Printf("Shutdown: <%s> finished.", name) | |
go func() { | |
waitCh <- name | |
}() | |
} | |
func Shutdown(timeout int) { | |
for name, ch := range waitingList { | |
log.Printf("Notifying <%s>.", name) | |
ch <- true | |
} | |
var timeoutCh <-chan time.Time | |
if timeout > 0 { | |
timeoutCh = time.After(time.Duration(timeout) * time.Millisecond) | |
} else { | |
timeoutCh = make(chan time.Time) | |
} | |
for { | |
select { | |
case name := <-waitCh: | |
delete(waitingList, name) | |
if len(waitingList) == 0 { | |
log.Printf("All done.") | |
return | |
} | |
case <-timeoutCh: | |
log.Printf("Timeout expired... unfinished processes:") | |
for name, _ := range waitingList { | |
log.Printf(name) | |
} | |
return | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment