Golang: 使用WaitTimeSeconds和Context参数来设置SQS ReceiveMessage的超时时间

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

Golang: Timing out SQS ReceiveMessage with WaitTimeSeconds vs with Context argument

问题

我可以使用以下代码调用SQS ReceiveMessage:

sqs.ReceiveMessageInput{
    QueueUrl:            &mysqr.poolQUrl,
    MaxNumberOfMessages: 1,
    WaitTimeSeconds:     5,
}

或者使用以下代码和context.TODO()

ctx := context.Background()
ctx2, cfn := context.WithTimeout(ctx, time.Second*5)
defer cfn()
rmo, err := svc.ReceiveMessage(ctx2, &rmi)

假设在5秒内没有可读取的内容。

在第一种情况下,它返回正常,没有消息和错误;而在第二种情况下,我会得到一个operation error SQS: ReceiveMessage, https response error StatusCode: 0, RequestID: , canceled, context deadline exceeded的错误。

AWS在Go SDK中提供了上下文(context),这是很好的。但我更愿意使用WaitTimeSeconds参数,因为它更简单。是否有一个好的原则性理由来使用context方法呢?

英文:

I can call SQS ReceiveMessage with

sqs.ReceiveMessageInput{
		QueueUrl: &mysqr.poolQUrl,
		MaxNumberOfMessages: 1,
		WaitTimeSeconds: 5,
	}

and context.TODO(), or with

	ctx := context.Background()
	ctx2, cfn := context.WithTimeout(ctx, time.Second * 5)
	defer cfn()
	rmo, err := svc.ReceiveMessage(ctx2, &rmi)

Let's assume there's nothing available to read in 5 seconds.

In the first case, it returns fine with no messages and no errors, in the second I get a operation error SQS: ReceiveMessage, https response error StatusCode: 0, RequestID: , canceled, context deadline exceeded.

It was nice of AWS to put context in the go SDK, but I'd rather use the WaitTimeSeconds argument, it just feels simpler. Is there a good principled reason to use the context approach instead?

答案1

得分: 2

AWS能在Go SDK中提供上下文是很好的。

你把WaitTimeSecondsReceiveMessages API的一部分)和你可能附加到上下文的超时混淆了。

WaitTimeSeconds是长轮询SQS队列的重要部分。如果没有它,空队列会导致消费者尽可能快地发起API请求,给AWS带来巨大的负载。超过WaitTimeSeconds并不表示错误——请求在网络不稳定的情况下可能需要更多的时间。

上下文可以用于在SDK本身之外的原因中断SDK操作,WithTimeout只是上下文的一种用法。在多线程应用程序中,您还可以使用上下文来取消由于应用程序其他地方的严重错误而产生的多个未完成的请求。

所以,首先,将WaitTimeSeconds视为超时是不正确的。其次,将上下文视为超时也是不正确的——上下文远不止于控制最大运行时间。

但我更愿意使用WaitTimeSeconds参数,它感觉更简单。

它们执行不同的功能。Context.WithTimeout并不取代WaitTimeSeconds。如果没有WaitTimeSeconds(或队列上的默认设置),ReceiveMessages将立即返回,而Context.WithTimeout将永远没有机会计时任何内容。

所以,没有,当然不是。使用上下文的好处是除了WaitTimeSeconds之外,甚至在某些情况下,Context.WithTimeout也可能与ReceiveMessages请求一起使用。但是,尽管它们都接受持续时间,但在用例中没有重叠。无论是否使用上下文,将WaitTimeSeconds设置为0几乎永远都是不正确的。

英文:

> It was nice of AWS to put context in the go SDK

You're conflating the WaitTimeSeconds, part of ReceiveMessages API, with the Timeout that you could potentially attach to a context.

WaitTimeSeconds is an important part of long polling SQS Queues. Without it, empty queues would cause consumers to make api requests as quickly as possible, driving huge loads on AWS. Exceeding the WaitTimeSeconds does not indicate errors - the request could legitimately take even many extra seconds on a degraded network.

Contexts can be used to abort SDK operations for reasons outside the realm of the SDK itself - WithTimeout is only one such use of contexts. In a multithreaded application, you might also use a context to cancel multiple outstanding requests due to some fatal error elsewhere in the application.

So, firstly, thinking of WaitTimeSeconds as a timeout is incorrect. Secondly, thinking of Context as a timeout is also incorrect - a context is much more than just controlling max runtime.

> but I'd rather use the WaitTimeSeconds argument, it just feels simpler.

They do different things. Context.WithTimeout doesn't obviate WaitTimeSeconds. Without WaitTimeSeconds (or a default setting on the queue), ReceiveMessages would return immediately and Context.WithTimeout would never get a chance to time anything out.

> Is there a good principled reason to use the context approach instead?

So no, certainly not. There's a good reason to use contexts in addition to WaitTimeSeconds - even Context.WithTimeout might make sense with ReceiveMessages requests in some situations. But even though they both take durations, there is no overlap in use case. With or without a context, it's almost never correct to run ReceiveMessages with WaitTimeSeconds set to 0.

huangapple
  • 本文由 发表于 2021年10月19日 06:49:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/69623364.html
匿名

发表评论

匿名网友

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

确定