go - 如何限制goroutine

标签 go google-api gmail-api goroutine

我正在开发一个基于 google api 的 gmail 客户端。

我有一个通过这个调用得到的标签列表

r, err := s.gClient.Service.Users.Labels.List(s.gClient.User).Do()

然后,我需要获取每个标签的详细信息

for _, l := range r.Labels {
    d, err := s.gClient.Service.Users.Labels.Get(s.gClient.User, l.Id).Do()
}

我想以更强大的方式处理循环,所以我在循环中实现了一个 goroutine:

ch := make(chan label.Label)

for _, l := range r.Labels {

    go func(gmailLabels *gmailclient.Label, gClient *gmail.Client, ch chan<- label.Label) {

        d, err := s.gClient.Service.Users.Labels.Get(s.gClient.User, l.Id).Do()

        if err != nil {
            panic(err)
        }

        // Performs some operation with the label `d`
        preparedLabel := ....

        ch <- preparedLabel

    }(l, s.gClient, ch)
}

for i := 0; i < len(r.Labels); i++ {
    lab := <-ch
    fmt.Printf("Processed %v\n", lab.LabelID)
}

这段代码的问题是 gmail api 有一个速率限制,所以,我得到这个错误:

panic: googleapi: Error 429: Too many concurrent requests for user, rateLimitExceeded

处理这种情况的正确方法是什么?

最佳答案

如何只开始例如10 个 goroutines 并将值从一个 for 循环传递到另一个 go 例程。 channel 有一个小缓冲区以减少同步时间。

chIn := make(chan label.Label, 20)
chOut := make(chan label.Label, 20)

for i:=0;i<10;i++ {
    go func(gClient *gmail.Client, chIn chan label.Label, chOut chan<- label.Label) {

        for gmailLabels := range chIn {
            d, err := s.gClient.Service.Users.Labels.Get(s.gClient.User, l.Id).Do()

            if err != nil {
                panic(err)
            }

            // Performs some operation with the label `d`
            preparedLabel := ....

            chOut <- preparedLabel

        }

    }(s.gClient, chIn, chOut)

}

go func(chIn chan label.Label) {
    defer close(chIn)
    for _, l := range r.Labels {
        chIn <- l
    }
}(chIn)

for i := 0; i < len(r.Labels); i++ {
    lab := <-chOut
    fmt.Printf("Processed %v\n", lab.LabelID)
}

编辑:

这里是playground sample .

关于go - 如何限制goroutine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45544133/

相关文章:

c - 为什么 Go 似乎无法识别 C 头文件中的 size_t?

java - 使用 Golang 中的类路径和库路径运行 Java 命令

android - Google Play 游戏服务错误代码 400

google-api - BigQuery 休息 API

java - 使用 Gmail API 发送的电子邮件偶尔会阻止 Gmail 帐户

go - 范围使用是否需要 channel 容量?

json - 去 json 休息 : JSON payload is empty

python - GAE/Google API 刷新访问 token 时出现 DeadlineExceededErrors

java - 使用 Gmail API 下载附件失败

javascript - 如何在没有 NodeJs 的情况下保持登录 Gmail api?