Enabling Long Polling in Amazon SQS Queues - AWS SDK for Go (version 1)

We announced the upcoming end-of-support for AWS SDK for Go V1. We recommend that you migrate to AWS SDK for Go V2. For dates, additional details, and information on how to migrate, please refer to the linked announcement.

Enabling Long Polling in Amazon SQS Queues

These AWS SDK for Go examples show you how to:

  • Enable long polling when you create an Amazon SQS queue

  • Enable long polling on an existing Amazon SQS queue

  • Enable long polling when a message is received

You can download complete versions of these example files from the aws-doc-sdk-examples repository on GitHub.

Scenario

Long polling reduces the number of empty responses by allowing Amazon SQS to wait a specified time for a message to become available in the queue before sending a response. Also, long polling eliminates false empty responses by querying all of the servers instead of a sampling of servers. To enable long polling, you must specify a non-zero wait time for received messages. You can do this by setting the ReceiveMessageWaitTimeSeconds parameter of a queue or by setting the WaitTimeSeconds parameter on a message when it is received.

The code uses these methods of the Amazon SQS client class:

Prerequisites

  • You have set up and configured the AWS SDK for Go.

  • You are familiar with Amazon SQS polling. To learn more, see Long Polling in the Amazon SQS Developer Guide.

Enable Long Polling When Creating a Queue

This example creates a queue with long polling enabled. If the queue already exists, no error is returned.

Create a new Go file named CreateLPQueue.go. You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

import ( "flag" "fmt" "strconv" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sqs" )

Get the queue name and wait time from the command line. Ensure that the wait time is between 0 (zero) and 20 seconds.

queue := flag.String("q", "", "The name of the queue") waitTime := flag.Int("w", 10, "How long, in seconds, to wait for long polling") flag.Parse() if *queue == "" { fmt.Println("You must supply a queue name (-q QUEUE") return } if *waitTime < 1 { *waitTime = 1 } if *waitTime > 20 { *waitTime = 20 }

Initialize a session that the SDK will use to load credentials from the shared credentials file, ~/.aws/credentials and the default AWS Region from ~/.aws/config.

sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, }))

Create a service client and call CreateQueue, passing in the time to wait for messages.

svc := sqs.New(sess) result, err := svc.CreateQueue(&sqs.CreateQueueInput{ QueueName: queueName, Attributes: aws.StringMap(map[string]string{ "ReceiveMessageWaitTimeSeconds": strconv.Itoa(*waitTime), }), })

See the complete example on GitHub.

Enable Long Polling on an Existing Queue

Create a new Go file named ConfigureLPQueue.go.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

import ( "flag" "fmt" "strconv" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sqs" )

Get the queue name and the optional timeout value from the command line. Ensure that the wait time is between 1 and 20 seconds.

queue := flag.String("q", "", "The name of the queue") waitTime := flag.Int("w", 10, "The wait time, in seconds, for long polling") flag.Parse() if *queue == "" { fmt.Println("You must supply a queue name (-q QUEUE") return } if *waitTime < 1 { *waitTime = 1 } if *waitTime > 20 { *waitTime = 20 }

Initialize a session that the SDK will use to load credentials from the shared credentials file, ~/.aws/credentials, and a default AWS Region from ~/.aws/config.

sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, }))

Get the URL of the queue.

svc := sqs.New(sess) result, err := svc.GetQueueUrl(&sqs.GetQueueUrlInput{ QueueName: queue, })

The URL is in the QueueUrl property of the returned object.

queueURL := result.QueueUrl

Update the queue to enable long polling with a call to SetQueueAttributes, passing in the queue URL.

_, err := svc.SetQueueAttributes(&sqs.SetQueueAttributesInput{ QueueUrl: queueURL, Attributes: aws.StringMap(map[string]string{ "ReceiveMessageWaitTimeSeconds": strconv.Itoa(aws.IntValue(waitTime)), }), })

See the complete example on GitHub.

Enable Long Polling on Message Receipt

Create a new Go file named ReceiveLPMessage.go.

You must import the relevant Go and AWS SDK for Go packages by adding the following lines.

import ( "flag" "fmt" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sqs" )

Get the queue name and optional visibility and wait time values from the command line. Ensure that the visibility is between 0 (zero) seconds and 12 hours and that the wait time is between 0 and 20 seconds.

queue := flag.String("q", "", "The name of the queue") waitTime := flag.Int64("w", 10, "How long the queue waits for messages") flag.Parse() if *queue == "" { fmt.Println("You must supply a queue name (-q QUEUE") return } if *waitTime < 0 { *waitTime = 0 } if *waitTime > 20 { *waitTime = 20 }

Initialize a session that the SDK will use to load credentials from the shared credentials file, ~/.aws/credentials and the default AWS Region from ~/.aws/config.

sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, }))

Create a service client and call GetQueueUrl to get the URL of the queue.

svc := sqs.New(sess) result, err := svc.GetQueueUrl(&sqs.GetQueueUrlInput{ QueueName: queue, })

Call ReceiveMessage to get the messages, using long polling, from the queue.

result, err := svc.ReceiveMessage(&sqs.ReceiveMessageInput{ QueueUrl: queueURL, AttributeNames: aws.StringSlice([]string{ "SentTimestamp", }), MaxNumberOfMessages: aws.Int64(1), MessageAttributeNames: aws.StringSlice([]string{ "All", }), WaitTimeSeconds: waitTime, })

Display the IDs of the mesages.

fmt.Println("Message IDs:") for _, msg := range msgs { fmt.Println(" " + *msg.MessageId) }

See the complete example on GitHub.