since I wasn't able to find anything about my specific problem, I'm going to ask this for myself here.
I've got this API for workers in Go:
package workerapi
import (...)
var MaxWorkers int = 1 << 16
type Job interface {
Run()
}
type Pool struct {
workers sync.WaitGroup
jobqueue chan Job
}
func NewPool(n int) (*Pool, error) {
if n <= 0 {
return nil, fmt.Errorf("worker: number of workers(n=%d) is <= 0", n)
}
if n > MaxWorkers {
return nil, fmt.Errorf("worker: number of workers(n=%d) is > MaxWorkers(%d)", n, MaxWorkers)
}
p := &Pool{jobqueue: make(chan Job)}
p.workers.Add(n)
for i := 1; i <= n; i++ {
go p.worker()
}
return p, nil
}
func (p *Pool) worker() {
for job := range p.jobqueue {
job.Run()
}
p.workers.Done()
}
func (p *Pool) SubmitAndWait(jobs ...Job) {
for _, job := range jobs {
p.jobqueue <- job
}
close(p.jobqueue)
p.workers.Wait()
}
My task is now to build an infinite loop of Jobs. This is, what I have so far:
package workertest
import (...)
type job struct {
id int
// later on, these will contain more data
}
func (j job) Run() {
sleep := rand.Intn(100)
fmt.Printf("job %3d: Start (%dms)\n", j.id, sleep)
time.Sleep(time.Duration(sleep) * time.Millisecond)
// here some more calculation
fmt.Printf("job %3d: Stopped (%dms)\n", j.id, sleep)
}
func Start(args []string) {
nrJobs := len(args)
const nrWorkers = 5
fmt.Printf("Starting %3d workers\n", nrWorkers)
p, err := workerapi.NewPool(nrWorkers)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Submitting %3d jobs\n", nrJobs)
jobs := make([]workerapi.Job, nrJobs)
for i := 0; i < nrJobs; i++ {
jobs[i] = job{i + 1, args[i]}
}
fmt.Println("Submit and Wait ...")
p.SubmitAndWait(jobs...)
fmt.Println("Finished all jobs")
}
The code above runs every given Job once with 5 workers in total. My goal is to put a finished job into the jobqueue again. But I don't know, how to manage this. Any advice is welcome!
Aucun commentaire:
Enregistrer un commentaire