我们说我有一个任务提供者 - 可读渠道,它可能会也可能不会提供任务(取决于工作量) 具体是因为几个小时可能没有工作,然后任务可能突然出现
我想让我的goroutine池从1增长到N,其中N是工作出现时的最大并发数,然后自动折叠到1,其中goroutine的工作时间超过X秒以避免内存/ cpu浪费
我本来可以只使用一个固定的游泳池,因为goroutines很便宜,但我不想拥有成千上万的闲置goroutines我可能更好地利用这些资源(应该主要是ram但仍然)
折叠部分非常简单
for {
timeoutTimer := time.NewTimer(WORKER_ROUTINE_TIMEOUT)
select {
case taskContext, isBatchRunning := <-runner.tasksCh:
if !isBatchRunning {
log.Print("task provider is closed, quit worker goroutine")
return
}
runner.job.Process(&taskContext)
case <-timeoutTimer.C:
return
}
}
但我不确定如何让游泳池动态增长,即哪种情况会产生一个新的
此池的优先级是能够在增加的负载下快速做出反应并扩展到N(最大并发)goroutine,当工作负载减少时能够最终崩溃到更合理的数字(1分钟)
P.S。我看到了一个https://github.com/Jeffail/tunny包,但看起来它没有类似于当前池大小的自适应缩放。我错过了什么吗?
谢谢!
答案 0 :(得分:1)
嗯,我不确定你需要一个游泳池。 Goroutines很快就会推出,你可能不需要一直保持它们的准备状态。
对于这个任务,我会使用一个简单的信号量。使用频道在Go中实现信号量非常容易。您可以看到我的个人示例here。
您只需创建一个具有所需容量的信号量(这将是您允许的最大goroutines数量)然后:
这很简单。 并且不用担心需要按需启动它们;它真的过度优化了。