0

我是 Go lang 的新手,正在尝试实现受限的 GCP API 调用。即限制我的应用程序每秒进行的 API 调用次数,因此 Google 不会阻止我。

我一直在关注此处示例的工作池模式。

与链接示例类似的设计将是:

  • 使两个通道(作业、结果)的容量与要进行的 API 调用总数相同
  • 创建一个一定大小的工人池(比如 10 个工人)
  • 每个工作人员在进行 API 调用时通过作业通道,并将响应存储到结果通道中,等待时间为 1 秒

我的问题是:

  • 我是否理解正确,10 名工作人员每人有 1 秒的等待期意味着我的应用每秒大约进行 10 次 API 调用?
  • 这 10 个工作人员如何相互通信,以免他们踩到对方的脚趾,即两个工作人员不查询相同的 GCS 路径。

当然还有一个终极问题:使用工作池是不是有点矫枉过正?

谢谢!

4

1 回答 1

0

也许你可以使用 Sync.Mutex 和 time.After 来实现一个 Throttler,如下所示

package main

import (
    "fmt"
    "os"
    "os/signal"
    "sync"
    "syscall"
    "time"
)

type Throttler struct {
    invocations int
    duration time.Duration
    m sync.Mutex
    max int
}

func (t *Throttler) Throttle() {
    t.m.Lock()
    defer t.m.Unlock()
    t.invocations += 1
    if t.invocations >= t.max {
        <-time.After(t.duration) // This block until the time period expires
        t.invocations = 0
    }
}

func main() {
    t := &Throttler{
        max: 2,
        duration: time.Second,
    }
    // Launch your workers passing in the throttler created above.
    for i := 0; i < 10; i++ {
        fmt.Println("starting worker")
        go Worker(t);
    }

    // This just to prevent the main from exiting.
    c := make(chan os.Signal)
    signal.Notify(c, os.Interrupt, syscall.SIGTERM)
    <-c // This will block until you manually exists with CRl-C
}

// worker
func Worker(t *Throttler)  {
    t.Throttle()
    fmt.Println("Work done!!")
}
于 2020-06-03T03:46:28.110 回答