为了账号安全,请及时绑定邮箱和手机立即绑定

“golang.org/x/time/rate”和上下文

“golang.org/x/time/rate”和上下文

Go
偶然的你 2023-01-03 11:16:46
在下面的示例中将上下文传递给 Wait() 函数的目的是什么?假设有一个限制器允许每秒 3 个请求。这是否意味着限制器不会成为共享资源,对于每个“进程”函数调用,它都会有自己的限制器实例和范围,对吗?如果不是这样呢?我怎样才能实现它?结构体type MyClass struct {    limiter *rate.Limiter}func NewMyClass() (*MyClass, error) {    return &MyClass{limiter: rate.NewLimiter(rate.Limit(3), 1)}, nil}func (m *MyClass) Process(ctx context.Context) error {    err := m.limiter.Wait(ctx)    if err != nil {        return err    }    //more code}例子m, _ := s3Storage.NewMyClass()        ctx1 := context.TODO()    m.Process(ctx1)    m.Process(ctx1)    m.Process(ctx1)    ctx2 := context.TODO()    m.Process(ctx2)
查看完整描述

2 回答

?
蓝山帝景

TA贡献1843条经验 获得超7个赞

首先,您需要了解rate.Limitercontext.Context类型的不同用途。允许您控制并发进程的Limiter执行速率。如果Context一个进程或一组进程继续下去没有意义(例如超时、丢失连接、用户取消...),则允许终止该进程或一组进程。这些是简化,因此请阅读 doco 以获取更多信息。

回答你的问题:

在示例中将上下文传递给 Wait() 函数的目的是什么?

没有任何目的,因为TODO上下文永远不会被取消。

这是否意味着限制器不会成为共享资源...?

不,它是共享的。你只有一个只有一个的MyClass实例Limiter

如果没有……我怎样才能实现呢?

在每个 Process 函数调用上设置限制器是没有意义的,因为一次调用永远不会超过 3 的限制。

认为您想要对 进行多组不同的限速调用Process,因此可能只需要 的多个实例MyClass,每个实例都有自己的Limiter

我不确定你到底想做什么,但作为一个例子,速率限制器的典型用途是限制用户或连接的进程数。类似地,上下文可能与附加到单个连接的所有进程相关联,因此如果连接终止,一切都可以被整齐地清除。所以一个可能的场景是你有一个Connection有 aLimiter和 a的类型Context

我希望这是有道理的。


查看完整回答
反对 回复 2023-01-03
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

上下文定义了调用的生命周期,所以如果上下文被取消,那么 wait 调用也将被取消。例如,尝试将上下文从 更改context.TODO()context.WithTimeout()具有非常小的超时并观察对 Wait() 调用的影响。官方文档很好地解释了背后的上下文和语义context



查看完整回答
反对 回复 2023-01-03
  • 2 回答
  • 0 关注
  • 77 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信