转到,如何一次从通道中提取X消息

时间:2013-12-31 10:01:20

标签: go

我有一个带有传入消息的频道和一个等待它的go例程 我处理这些消息并将它们发送到不同的服务器

如果他们准备就绪,我想一次处理100封邮件, 或者说5秒后处理那里的东西并再次等待

我如何在Go

中执行此操作

1 个答案:

答案 0 :(得分:9)

用于从消息通道读取的例程应定义存储传入消息的高速缓存。然后,当缓存达到100条消息或已过去5秒时,这些缓存的消息将批量发送到远程服务器。您使用计时器通道和Go的select语句来确定首先出现哪个。

以下示例可以在Go playground

上运行
package main

import (
    "fmt"
    "math/rand"
    "time"
)

type Message int

const (
    CacheLimit   = 100
    CacheTimeout = 5 * time.Second
)

func main() {
    input := make(chan Message, CacheLimit)

    go poll(input)
    generate(input)
}

// poll checks for incoming messages and caches them internally
// until either a maximum amount is reached, or a timeout occurs.
func poll(input <-chan Message) {
    cache := make([]Message, 0, CacheLimit)
    tick := time.NewTicker(CacheTimeout)

    for {
        select {
        // Check if a new messages is available.
        // If so, store it and check if the cache
        // has exceeded its size limit.
        case m := <-input:
            cache = append(cache, m)

            if len(cache) < CacheLimit {
                break
            }

            // Reset the timeout ticker.
            // Otherwise we will get too many sends.
            tick.Stop()

            // Send the cached messages and reset the cache.
            send(cache)
            cache = cache[:0]

            // Recreate the ticker, so the timeout trigger
            // remains consistent.
            tick = time.NewTicker(CacheTimeout)

        // If the timeout is reached, send the
        // current message cache, regardless of
        // its size.
        case <-tick.C:
            send(cache)
            cache = cache[:0]
        }
    }
}

// send sends cached messages to a remote server.
func send(cache []Message) {
    if len(cache) == 0 {
        return // Nothing to do here.
    }

    fmt.Printf("%d message(s) pending\n", len(cache))
}

// generate creates some random messages and pushes them into the given channel.
//
// Not part of the solution. This just simulates whatever you use to create
// the messages by creating a new message at random time intervals.
func generate(input chan<- Message) {
    for {
        select {
        case <-time.After(time.Duration(rand.Intn(100)) * time.Millisecond):
            input <- Message(rand.Int())
        }
    }
}