如何使用渠道批量处理golang管道阶段中的项目?

时间:2017-08-24 23:41:40

标签: go concurrency pipeline channel

我正在网上阅读管道教程并尝试构建一个像这样运行的舞台 -

  1. 在将传入事件发送到out chan
  2. 之前,分批批量处理每个事件10个
  3. 如果我们在5秒钟内没有看到10个事件,请结合我们收到的数量并发送它们,关闭out chan并返回。
  4. 然而,我不知道第一个选择的案例会是什么样子。多件事情已经结束但是无法解决这个问题。 任何指针都非常赞赏!

    func BatchEvents(inChan <- chan *Event) <- chan *Event {
        batchSize := 10
        comboEvent := Event{}
        go func() {
            defer close(out)
            i = 0
            for event := range inChan {
                select {
                case -WHAT GOES HERE?-:
                    if i < batchSize {
                        comboEvent.data = append(comboEvent.data, event.data)
                        i++;
                    } else {
                        out <- &comboEvent
                        // reset for next batch
                        comboEvent = Event{}
                        i=0;
                    }
                case <-time.After(5 * time.Second):
                    // process whatever we have seen so far if the batch size isn't filled in 5 secs
                    out <- &comboEvent
                    // stop after
                    return
                }
            }
        }()
        return out
    }
    

1 个答案:

答案 0 :(得分:1)

而不是在频道上做一个范围,你的第一个选择案例应该来自那个频道,整个事情都在一个无限循环内。

func BatchEvents(inChan <-chan *Event) <-chan *Event {
    batchSize := 10
    comboEvent := Event{}
    go func() {
        defer close(out)
        i = 0
        for {
            select {
            case event, ok := <-inChan:
                if !ok {
                    return
                }
                comboEvent.data = append(comboEvent.data, event.data)
                i++
                if i == batchSize {
                    out <- &comboEvent
                    // reset for next batch
                    comboEvent = Event{}
                    i = 0
                }
            case <-time.After(5 * time.Second):
                // process whatever we have seen so far if the batch size isn't filled in 5 secs
                if i > 0 {
                    out <- &comboEvent
                }
                // stop after
                return
            }
        }
    }()
    return out
}