"golang.org/x/time/rate" and Context

huangapple go评论75阅读模式
英文:

"golang.org/x/time/rate" and Context

问题

在下面的示例中,将上下文传递给Wait()函数的目的是为了在执行操作之前等待上下文完成或取消。

假设有一个每秒允许3个请求的限制器。

这是否意味着限制器不会成为共享资源,也就是说,对于每个"Process"函数调用,它将拥有自己的限制器实例和作用域,是这样吗?
如果不是这种情况,我该如何实现?

结构体

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
	}
	//更多代码
}

示例

m, _ := s3Storage.NewMyClass()
	
	ctx1 := context.TODO()
	m.Process(ctx1)
	m.Process(ctx1)
	m.Process(ctx1)

	ctx2 := context.TODO()
	m.Process(ctx2)
英文:

What's the purpose of passing the context to Wait() function in the example below?

Let's say there is a limiter that allow 3 requests per second.

Does it mean that limiter will not be a shared resource in the sense that, for each "Process" function call, it will have it's own limiter instance and scope, is that right?
If it's not the case? How can I achieve it?

Struct

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
}

Example

m, _ := s3Storage.NewMyClass()
	
	ctx1 := context.TODO()
	m.Process(ctx1)
	m.Process(ctx1)
	m.Process(ctx1)

	ctx2 := context.TODO()
	m.Process(ctx2)

答案1

得分: 3

首先,你需要理解rate.Limitercontext.Context类型的不同用途。Limiter允许你控制并发进程的执行速率。Context允许在没有继续执行的必要时终止一个进程或一组进程(例如超时、连接丢失、用户取消等)。这些只是简化,更多信息请阅读文档。

回答你的问题:

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

没有目的,因为TODO上下文从未被取消。

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

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

如果不是...我该如何实现?

在每次调用Process函数时都使用限制器没有意义,因为一次调用永远不会超过你的限制(3)。

猜测你想要多个不同的受速率限制的Process调用集合,所以可能只需要多个MyClass实例,每个实例都有自己的Limiter

我不确定你具体想要做什么,但一个典型的限制器使用场景是按用户或连接限制进程数量。类似地,一个上下文可能与一个连接关联,这样如果连接断开,所有的进程都可以被清理干净。所以一个可能的情景是你有一个Connection类型,它有一个Limiter和一个Context

希望这样说得清楚些。

英文:

First, you need to understand the different purposes of the rate.Limiter and context.Context types. The Limiter allows you to control the rate at which concurrent processes are executed. The Context allows to terminate a process or group of processes if there is no point in them continuing (eg timeout, lost connection, user-cancellation...). These are simplifications so read the doco for more info.

To answer your questions:

> What's the purpose of passing the context to Wait() function in the example?

There is no purpose as the TODO context is never cancelled.

> Does it mean the limiter will not be a shared resource...?

No, it is shared. You only have one MyClass instance which only has one Limiter.

> If not ... how can I achieve it?

There is no point in having a limiter on each Process function call, since one call will never exceed your limit of 3.

I think you want multiple different sets of rate-limited calls to Process, and so probably just need multiple instances of MyClass, each with it's own Limiter.

I'm not sure exactly what you are trying to do, but as an example a typical use of a rate limiter is to restrict the number of processes by user or by connection. Similarly, a context may be associated with all the processes attached to a single connection, so that if the connection dies everything can be neatly cleaned up. So a possible scenario is that you have a Connection type that has a Limiter and a Context.

I hope this makes sense.

答案2

得分: 2

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

英文:

The context defines the lifetime of the call, so if the context is cancelled, then the wait call will be cancelled as well. As an example, try changing the context from context.TODO() to context.WithTimeout() with a very small timeout and observe the effect on the Wait() call. The official docs do a good job of explaining the context and semantics behind context.

huangapple
  • 本文由 发表于 2022年7月7日 10:04:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/72891546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定