Skip to content

Instantly share code, notes, and snippets.

@blixt
Last active August 29, 2015 14:17
Show Gist options
  • Save blixt/099c10f7a2f38ffc688c to your computer and use it in GitHub Desktop.
Save blixt/099c10f7a2f38ffc688c to your computer and use it in GitHub Desktop.
Stoppable workers with reporting
// Playground: http://play.golang.org/p/G9-_EtwPRg
package main
import (
"fmt"
"math/rand"
"time"
)
type WorkerId int
func work(id WorkerId, stop <-chan chan<- WorkerId) {
fmt.Printf("[work] Working on stuff in worker %d...\n", id)
select {
case report := <-stop:
sleepyTime := time.Duration(500+rand.Intn(2000)) * time.Millisecond
time.Sleep(sleepyTime)
fmt.Printf("[work] Worker %d shut down in %s!\n", id, sleepyTime)
report <- id
break
}
}
const (
numWorkers = 10
timeout = 2 * time.Second
)
func main() {
fmt.Println("[main] Starting up workers...")
stops := make([]chan chan<- WorkerId, numWorkers)
for i := 0; i < numWorkers; i++ {
stop := make(chan chan<- WorkerId, 1)
go work(WorkerId(i+1), stop)
stops[i] = stop
}
time.Sleep(100 * time.Millisecond)
fmt.Println("[main] Asking workers to shut down...")
report := make(chan WorkerId, numWorkers)
for i := 0; i < numWorkers; i++ {
stops[i] <- report
}
fmt.Println("[main] Waiting for workers to shut down...")
deadline := time.After(timeout)
for i := 0; i < numWorkers; i++ {
fmt.Printf("[main] %d worker(s) left\n", numWorkers-i)
select {
case id := <-report:
fmt.Printf("[main] Worker %d reported back\n", id)
continue
case <-deadline:
fmt.Println("[main] Timed out waiting for workers to shut down")
return
}
}
fmt.Println("[main] That's all folks!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment