Golang:使用 WaitTimeSeconds 与 Context 参数使 SQS ReceiveMessage 超时

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 秒内没有任何内容可供阅读。

在第一种情况下,它 returns 很好,没有消息也没有错误,在第二种情况下,我得到 operation error SQS: ReceiveMessage, https response error StatusCode: 0, RequestID: , canceled, context deadline exceeded

AWS 将上下文放在 go SDK 中真是太棒了,但我宁愿使用 WaitTimeSeconds 参数,它只是感觉更简单。是否有充分的原则性理由改用 context 方法?

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

您将WaitTimeSecondsReceiveMessagesAPI的一部分与您可以可能附加到上下文的超时混为一谈.

WaitTimeSeconds 是长轮询 SQS 队列的重要组成部分。没有它,空队列会导致消费者尽快发出 api 请求,从而在 AWS 上产生巨大的负载。超过 WaitTimeSeconds 并不表示错误 - 在降级的网络上,请求可能会合法地花费更多的秒数。

上下文可用于出于 SDK 本身范围之外的原因中止 SDK 操作 - WithTimeout 只是上下文的一种此类用途。在多线程应用程序中,由于应用程序其他地方的某些致命错误,您还可以使用上下文来取消多个未完成的请求。

因此,首先,将 WaitTimeSeconds 视为超时是不正确的。其次,将 Context 视为超时也是不正确的 - 上下文不仅仅是控制最大 运行time.

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

他们做不同的事情。 Context.WithTimeout 不排除 WaitTimeSeconds。如果没有 WaitTimeSeconds(或队列中的默认设置),ReceiveMessages 会立即 return 而 Context.WithTimeout 永远不会有任何超时的机会。

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

所以不,当然不是。除了 WaitTimeSeconds 之外,还有一个很好的理由使用上下文 - 在某些情况下,甚至 Context.WithTimeout 也可能对 ReceiveMessages 请求有意义。但即使它们都需要持续时间,用例也没有重叠。无论有没有上下文,运行 ReceiveMessages 几乎永远不会正确 WaitTimeSeconds 设置为 0.