“什么?”你问,“那个标题没有任何意义。”
请考虑以下内容: 具有不同ID的作业可以异步处理,但是具有相同ID的作业应按照队列中的顺序进行同步处理。
我当前的实现创建了一个go例程来处理每个特定ID的作业,看起来像这样:
func FanOut() chan<- *Job {
channel := make(chan *Job)
routines = make(map[string]chan<- *Job)
go func() {
for j := range channel {
r, found := routines[j.id]
if !found {
r = Routine()
routines[j.id] = r
}
r <- j
}
}()
return channel
}
这似乎很好(在当前测试中),但是创建数千个go例程可能不是最佳方法吗?另外,除非使用了缓冲通道,否则扇出代码块会消失。
我正在考虑使用sync.Mutex的集合,而不是上面的go例程的集合。想法是要有一个go例程例程,这些例程必须首先在对应于作业id的互斥锁上建立锁定。
是否存在适合处理这些需求的Go模式?
有更好的方法吗?
答案 0 :(得分:1)
为每个ID创建一个通道-可能是通道的一部分或地图(按ID索引)。每个通道都有一个例程,该例程按顺序处理该ID的作业。很简单。
我不会担心创建太多的例程。而且我不会使用互斥体-如果不使用通道进行过多的详细说明,那么go-routines只能一次只通过一个go-routine处理每个作业,并且避免了数据争用的可能性。
顺便说一句,我只是将其添加为答案,因为我不允许添加评论(还?)。