mardi 31 juillet 2018

GoLang - given this Worker-API, how do I create an infinite loop of Jobs?

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