Skip to content

Instantly share code, notes, and snippets.

@shicky
Created July 5, 2016 04:56
Show Gist options
  • Save shicky/966113ce9c0829b485549efe44c7fddd to your computer and use it in GitHub Desktop.
Save shicky/966113ce9c0829b485549efe44c7fddd to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"sync"
"time"
)
type Job struct {
url string
}
type Worker struct {
id int
}
func (w *Worker) Process(job interface{}) {
j, ok := job.(Job)
if ok {
fmt.Printf("worker %d: processing %s\n", w.id, j.url)
time.Sleep(2)
}
}
type Dispatcher struct {
numWorkers int
jobChannel chan interface{}
waitGroup *sync.WaitGroup
}
func NewDispatcher(numWorkers int) *Dispatcher {
return &Dispatcher{
numWorkers,
make(chan interface{}),
&sync.WaitGroup{},
}
}
func (d *Dispatcher) StartWorkers() {
d.waitGroup.Add(d.numWorkers)
for i := 0; i < d.numWorkers; i++ {
worker := Worker{i}
go func(worker Worker) {
for job := range d.jobChannel {
worker.Process(job)
}
d.waitGroup.Done()
}(worker)
}
}
func (d *Dispatcher) Submit(job interface{}) {
// this will not be blocked!
d.jobChannel <- job
}
func (d *Dispatcher) Close() {
// close job channel
close(d.jobChannel)
// wait for all jobs to finish
d.waitGroup.Wait()
}
func main() {
dispatcher := NewDispatcher(5)
dispatcher.StartWorkers()
for i := 0; i < 30; i++ {
dispatcher.Submit(
Job{
fmt.Sprintf("Job Number %d", i),
},
)
}
dispatcher.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment