有了这个Worker-API,我如何创建Jobs的无限循环?

时间:2018-07-31 09:04:58

标签: multithreading go design-patterns api-design

由于我无法找到有关我的特定问题的任何信息,因此我将在这里自行询问。

我在Go语言中为工人提供了此API:

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()
}

我现在的任务是建立一个无限循环的乔布斯。这就是我到目前为止所拥有的:

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")
}

上面的代码对每个给定的Job运行一次,总共有5个工人。我的目标是将完成的工作再次放入工作队列。但是我不知道该如何处理。欢迎任何建议!

0 个答案:

没有答案