Skip to content

Instantly share code, notes, and snippets.

@aymone
Last active November 25, 2018 22:17
Show Gist options
  • Save aymone/f3eef45d9a480f85559de0e13a9b1865 to your computer and use it in GitHub Desktop.
Save aymone/f3eef45d9a480f85559de0e13a9b1865 to your computer and use it in GitHub Desktop.
worker pool implementantion
package job
import (
"fmt"
"math/rand"
"time"
"github.com/aymone/workerpool/service"
)
// Samplejob is a implementation of workerpool Job interface
type Samplejob struct {
ID int
service service.JobService
}
// New sample job service
func New(ID int, s service.JobService) *Samplejob {
return &Samplejob{ID, s}
}
// Do Job implementation
func (j *Samplejob) Do() {
waitSeconds := rand.Intn(15)
time.Sleep(time.Second * time.Duration(waitSeconds))
entity, err := j.service.Get(j.ID)
if err != nil {
fmt.Printf("\njob %d had error: %s", entity.ID, err.Error())
}
fmt.Printf("\njob %d done in %d seconds", entity.ID, waitSeconds)
}
package main
import (
"fmt"
"math/rand"
"time"
"github.com/aymone/workerpool/job"
"github.com/aymone/workerpool/service"
"github.com/aymone/workerpool/workerpool"
)
func main() {
const poolSize = 3
// pool
p := workerpool.New("My pool", poolSize)
// service
s := service.New()
counter := 0
for {
fmt.Print("\nChecking jobs")
hasJob := rand.Intn(3)
if hasJob > 0 {
counter++
fmt.Printf("\njob %d awaiting to be started", counter)
j := job.New(counter, s)
p.AddJob(j)
fmt.Printf("\njob %d added", counter)
}
time.Sleep(time.Second * 1)
}
}
package service
type (
// Entity ...
Entity struct {
ID int
}
service struct{}
)
// JobService interface
type JobService interface {
Get(ID int) (*Entity, error)
}
// New service
func New() *service {
return &service{}
}
func (s *service) Get(ID int) (*Entity, error) {
return &Entity{ID}, nil
}
package workerpool
import (
"fmt"
)
// Job interface
type Job interface {
Do()
}
type pool struct {
name string
size int
jobs chan Job
}
// New starts a pool of workers
func New(name string, poolSize int) *pool {
p := &pool{
name: name,
size: poolSize,
jobs: make(chan Job),
}
go p.process()
return p
}
func (p *pool) AddJob(j Job) {
p.jobs <- j
}
func (p *pool) process() {
tickets := make(chan bool, p.size)
fmt.Printf("\nProcessing pool '%s' with %d workers", p.name, p.size)
for j := range p.jobs {
tickets <- true
go func(j Job, t chan bool) {
j.Do()
<-t
}(j, tickets)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment