alitto / pond

🔘 Minimalistic and High-performance goroutine worker pool written in Go
MIT License
1.43k stars 60 forks source link

does pond support serial queue? #21

Closed haifenghuang closed 2 years ago

haifenghuang commented 2 years ago

I want a list of tasks to submit to the pool, and want the submitted task to complete one after one, can pond support this scenario?

for example: taskgroup1 have three tasks: task1, task2, task3

taskgroup2 have two tasks: task1, task2

taskgroup1 and taskgroup2 are all submitted to the pool, I want taskgroup1 and taskgroup2 run in concurrency. But in taskgroup1 and taskgroup2, the submitted tasks run one after another. i.e. in taskgroup1 when task1 finished, then task2 will run, and when task2 finished, task3 will run. In taskgroup2 when task1 finished, then task2 will run.

alitto commented 2 years ago

Hey @haifenghuang! I'm afraid that pattern is not supported by this library. I guess you could mimic that behavior if you group tasks into other functions that each run a subset of tasks one after the other (sequentially). For the sake of the example, let's say you have the following function, which takes a slice of tasks and returns another one where each element is a group of tasks which run sequentially:

func groupTasks(tasks []func(), groupSize int) (taskGroups []func()) {

    taskCount := len(tasks)
    groupCount := int(math.Ceil(float64(taskCount) / float64(groupSize)))

    var groupStart, groupEnd int

    for i := 0; i < groupCount; i++ {
        groupStart = i * groupSize
        groupEnd = int(math.Min(float64((i+1)*groupSize), float64(taskCount)))
        taskGroup := tasks[groupStart:groupEnd]
        taskGroups = append(taskGroups, func() {
            for _, task := range taskGroup {
                task()
            }
        })
    }

    return
}

Then you could submit these "grouped tasks" to a pool like this:

// Create pool
pool := pond.New(10, 1000)

// Split tasks in groups of up to 3 elements
groupedTasks := groupTasks(tasks, 3)

// Submit grouped tasks to the pool
for _, task := range groupedTasks {
    pool.Submit(task)
}

In your case though, you may want to group these tasks using different criteria. What do you think?

haifenghuang commented 2 years ago

Thanks a lot! Maybe I'm not express myself clearly. You are right, the example is what I wanted.

alitto commented 2 years ago

You're welcome!