Skip to content

Instantly share code, notes, and snippets.

@zgiber
Created February 6, 2018 21:53
Show Gist options
  • Save zgiber/46906e4c6e81c4cef73a25499abe9613 to your computer and use it in GitHub Desktop.
Save zgiber/46906e4c6e81c4cef73a25499abe9613 to your computer and use it in GitHub Desktop.
For Kai - It's relatively simple, and handles a few useful cases (ctrl+c, kind of graceful shutdown)
package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"strconv"
"sync"
"time"
)
const (
numWorkers = 4
)
// TestJob is something we need to process
type TestJob struct {
ID string `json:"id"`
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
jobs := make(chan *TestJob)
wg := &sync.WaitGroup{}
wg.Add(numWorkers)
for i := 0; i < numWorkers; i++ {
go runWorker(ctx, jobs, wg)
}
go listenForSignals(cancel)
outer:
for i := 0; i < 100; i++ {
jobID := strconv.Itoa(i)
select {
case jobs <- &TestJob{jobID}:
case <-time.After(1 * time.Second):
break outer
}
}
close(jobs)
wg.Wait()
}
func listenForSignals(cancel context.CancelFunc) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
cancel()
}
func runWorker(ctx context.Context, jobs chan *TestJob, wg *sync.WaitGroup) {
defer wg.Done()
defer fmt.Println("worker stopped")
for {
select {
case <-ctx.Done():
return
case job, ok := <-jobs:
if !ok {
return
}
doSomeWork(job)
}
}
}
func doSomeWork(job *TestJob) {
time.Sleep(500 * time.Millisecond)
_, err := fmt.Println(job.ID)
if err != nil {
log.Println(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment