Search code examples
amazon-web-servicesamazon-sqsasp.net-core-3.1aws-sdk-net

AWS SQS ReceiveMessageAsync not get messages if called with WaitTimeSeconds = 0


I have EventBridge pushing messages to SQS, and also SQS messages being consumed by a background process.

In background process, I am using following piece of code (executed with 1s delay):

var receiveMessageRequest = new ReceiveMessageRequest()
{
    QueueUrl = await GetQueueUrl(),
    WaitTimeSeconds = 0, // this is problematic line
    MaxNumberOfMessages = 1
};
var response = await _sqsClient.ReceiveMessageAsync(receiveMessageRequest);

The scenario is that I'm sending 1 messages to EventBridge and it is routed to SQS.

If I poll the queue with WaitTimeSeconds = 0 sometimes the message is received after 20-40 seconds (which oddly corresponds to SQS's Default visibility timeout = 30, not sure though).

If however, I am calling this function with WaitTimeSeconds = 1 then it works as expected, meaning message is received fast.

My crazy hypothesis is: it looks like if there is 1 message in a queue, and short polling is used, it is not visible for some reason.


Solution

  • as per the documentation

    This behaviour you see because of short vs long polling. Quoting from the documentation

    With short polling, the ReceiveMessage request queries only a subset of the servers (based on a weighted random distribution) to find messages that are available to include in the response. Amazon SQS sends the response right away, even if the query found no messages.

    With long polling, the ReceiveMessage request queries all of the servers for messages. Amazon SQS sends a response after it collects at least one available message, up to the maximum number of messages specified in the request. Amazon SQS sends an empty response only if the polling wait time expires.

    and at the bottom of the doc explains the behaviour which is short polling by setting the ** WaitTimeSeconds** var

    Short polling occurs when the WaitTimeSeconds parameter of a ReceiveMessage request is set to 0 in one of two ways:

    • The ReceiveMessage call sets WaitTimeSeconds to 0.
    • The ReceiveMessage call doesn’t set WaitTimeSeconds, but the queue attribute ReceiveMessageWaitTimeSeconds is set to 0.