Created
November 7, 2023 22:01
-
-
Save lajosbencz/32bc71159d08504661e452be0ece35fe to your computer and use it in GitHub Desktop.
Go - Graceful shutdown of goroutines with channel signaling
This file contains hidden or 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 ( | |
"fmt" | |
"os" | |
"os/signal" | |
"sync" | |
"syscall" | |
"time" | |
) | |
const burstSize = 3 | |
func main() { | |
defer fmt.Println("shut down gracefully.") | |
shutdown := make(chan os.Signal, 1) | |
defer close(shutdown) | |
signal.Notify(shutdown, os.Interrupt, syscall.SIGHUP, syscall.SIGINT) | |
eventChan := make(chan string, burstSize*3) | |
burstLimiter := make(chan struct{}, burstSize) | |
ticker := time.NewTicker(time.Second) | |
stopChan := make(chan struct{}) | |
wg := sync.WaitGroup{} | |
// dummy event procuder | |
wg.Add(1) | |
go func() { | |
defer wg.Done() | |
defer close(eventChan) | |
ticker1 := time.NewTicker(time.Millisecond * 320) | |
ticker2 := time.NewTicker(time.Millisecond * 690) | |
for { | |
select { | |
case <-ticker1.C: | |
fmt.Println("procuding event from ticker1") | |
eventChan <- "ticker1" | |
case <-ticker2.C: | |
fmt.Println("procuding event from ticker2") | |
eventChan <- "ticker2" | |
case <-stopChan: | |
fmt.Println("stopped event producer") | |
ticker1.Stop() | |
ticker2.Stop() | |
return | |
} | |
} | |
}() | |
// burst limiter producer | |
wg.Add(1) | |
go func() { | |
defer wg.Done() | |
defer close(burstLimiter) | |
for { | |
select { | |
case <-ticker.C: | |
for i := 0; i < burstSize; i++ { | |
burstLimiter <- struct{}{} | |
} | |
case <-stopChan: | |
fmt.Println("stopped burst limiter") | |
return | |
} | |
} | |
}() | |
loop: | |
for { | |
select { | |
case <-shutdown: | |
close(stopChan) | |
for range eventChan { | |
// drain channel so it's not blocking the writer | |
} | |
break loop | |
case msg := <-eventChan: | |
<-burstLimiter | |
fmt.Printf("%s %s\n", time.Now(), msg) | |
} | |
} | |
fmt.Println("shutting down gracefully...") | |
wg.Wait() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment