英文:
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中提供上下文是很好的。
你把WaitTimeSeconds
(ReceiveMessages
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论