Skip to content

Instantly share code, notes, and snippets.

@peterkellydev
Created September 27, 2016 14:47
Show Gist options
  • Save peterkellydev/645842faafaf493c4c26bed7aa28846e to your computer and use it in GitHub Desktop.
Save peterkellydev/645842faafaf493c4c26bed7aa28846e to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math/rand"
"os"
"os/signal"
"sync"
"time"
)
const maxWorkers = 3
func main() {
deliveries := make(chan int)
sending := make(chan bool)
var listeners [3]chan bool
var done sync.WaitGroup
// Spin up some workers
for i := 0; i < maxWorkers; i++ {
done.Add(1)
cancel := make(chan bool)
listeners[i] = cancel
go worker(i+1, deliveries, cancel, &done)
}
go func() {
Loop:
for {
select {
case <-sending:
break Loop
default:
deliveries <- rand.Intn(10)
time.Sleep(time.Second * 1)
}
}
}()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
fmt.Println("Signal received")
<-c
// stop sending
fmt.Println("Stop sending")
sending <- false
// stop consuming
fmt.Println("Stop workers")
for _, l := range listeners {
l <- true
}
// wait for each worker to signal done
fmt.Println("Waiting for workers to complete tasks...")
done.Wait()
fmt.Println("All done, exiting")
}
func worker(id int, deliveries chan int, cancel chan bool, done *sync.WaitGroup) {
Loop:
for {
select {
case d := <-deliveries:
process(id, d)
case <-cancel:
break Loop
}
}
fmt.Printf("Worker %d has finished all tasks, signalling compete...", id)
done.Done()
}
func process(id, d int) {
fmt.Printf("Worker %d processing task: %d\n", id, d)
time.Sleep(time.Second * time.Duration(d))
fmt.Printf("Worker %d completed task: %d\n", id, d)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment