Skip to content

Instantly share code, notes, and snippets.

@lummie
Created September 28, 2021 14:59
Show Gist options
  • Save lummie/0475b4604a7c40cf68f897791112b8cd to your computer and use it in GitHub Desktop.
Save lummie/0475b4604a7c40cf68f897791112b8cd to your computer and use it in GitHub Desktop.
Go channel based Simple Worker pattern
package main
import (
"fmt"
"log"
"sync"
)
/*
This is an example of a worker pattern for channels
*/
type WorkItem struct {
Num int
}
type WorkManager struct {
workToDo chan WorkItem
wgWork sync.WaitGroup // waitgroup for work items
}
func NewWorkManager(workBufferSize int) *WorkManager {
return &WorkManager{
workToDo: make(chan WorkItem, workBufferSize),
wgWork: sync.WaitGroup{},
}
}
func (w *WorkManager) Startup(workerCount int) {
for i := 0; i < workerCount; i++ {
go w.newWorker(i)
}
}
// newWorker is the implementation of the the work you need to do
// get some work to do of the channel and process it, then mark the work wg done
func (w *WorkManager) newWorker(id int) {
log.Printf("Worker %d started", id)
for workItem := range w.workToDo {
log.Printf("%v\n", workItem)
w.wgWork.Done() // mark work item as done
}
log.Printf("Worker %d finished", id)
}
func (w *WorkManager) AddWork(work WorkItem) {
w.wgWork.Add(1)
w.workToDo <- work // this will block if the channel becomes full as the workers are not working fast enough
}
func (w *WorkManager) WaitForWorkComplete() {
fmt.Println("Waiting for work to complete")
w.wgWork.Wait() // wait for any work to complete
fmt.Println("Work is complete")
}
func (w *WorkManager) Shutdown() {
w.WaitForWorkComplete()
close(w.workToDo) // close the work channel, this will cause each worker go routine to quit out the range exit nicely
}
func main() {
wm := NewWorkManager(100)
wm.Startup(10)
log.Println("create work items block 1")
for i := 0; i < 10; i++ {
wm.AddWork(WorkItem{Num: i})
}
wm.WaitForWorkComplete()
log.Println("create work items block 2")
for i := 0; i < 10; i++ {
wm.AddWork(WorkItem{Num: 1000 + i})
}
wm.Shutdown()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment