Skip to content

Instantly share code, notes, and snippets.

@hoangpq
Last active November 3, 2018 09:28
Show Gist options
  • Save hoangpq/e19919e2fef5ac2a6a6c26bb5a9a8223 to your computer and use it in GitHub Desktop.
Save hoangpq/e19919e2fef5ac2a6a6c26bb5a9a8223 to your computer and use it in GitHub Desktop.
Simple task queue in Golang
package main
import (
"fmt"
"github.com/satori/go.uuid"
"math/rand"
"sync"
"time"
)
type Job struct {
mu sync.Mutex
name string
duration int
}
func RunWorker(jobs chan Job, result chan Job, wg *sync.WaitGroup) {
for {
j, more := <-jobs
j.mu.Lock()
if more {
/** Long running task simulate **/
time.Sleep(time.Second * time.Duration(j.duration))
/** End long running task simulate **/
result <- j
wg.Done()
}
j.mu.Unlock()
}
}
func main() {
numOfJobs := 100
numOfWorkers := 10
jobs := make(chan Job, numOfJobs)
result := make(chan Job, numOfJobs)
start := time.Now()
wg := sync.WaitGroup{}
for i := 0; i < numOfWorkers; i++ {
go RunWorker(jobs, result, &wg)
}
done := make(chan bool)
go func() {
wg.Add(numOfJobs)
for i := 0; i < numOfJobs; i++ {
uid, _ := uuid.NewV4()
j := Job{sync.Mutex{}, uid.String(), rand.Intn(3) + 1}
jobs <- j
fmt.Printf("*** Sent %s [%ds] ***\n", j.name, j.duration)
}
close(jobs)
wg.Wait()
done <- true
}()
mu := sync.Mutex{}
realTotalTime := 0
for {
select {
case r := <-result:
mu.Lock()
realTotalTime = realTotalTime + r.duration
mu.Unlock()
fmt.Printf("*** Done %s ***\n", r.name)
case <-done:
fmt.Printf("*** Done %d jobs in %s [%d goroutines], %s [1 goroutine] ***\n",
numOfJobs, time.Since(start), numOfWorkers, time.Duration(realTotalTime) * time.Second)
return
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment