title: AWS SQS Listening vs Polling
body: <p>I currently have implemented in a Spring Boot project running on Fargate an SQS listener.</p>
  <p>It's possible that under the hood, the SqsAsyncClient which appears to be a listener, is actually polling though.</p>
  <p>Separately, as a PoC, on I implemented a Lambda function <em>trigger</em> on a different queue. This would be <em>invoked</em> when there are items in the queue and would post to my service. This seems unnecessarily complex to me but removes a single point of failure if I were to only have one instance of the service.</p>
  <p>I guess my major point of confusion is whether I am needlessly worrying about polling vs listening on a SQS queue and whether it matters.</p>
  <p>Code for example purposes:</p>
  <pre><code>@Component
  @Slf4j
  @RequiredArgsConstructor
  public class SqsListener {
  
  private final SqsAsyncClient sqsAsyncClient;
  private final Environment environment;
  private final SmsMessagingServiceImpl smsMessagingService;
  
  @PostConstruct
  public void continuousListener() {
      String queueUrl = environment.getProperty(&quot;aws.sqs.sms.queueUrl&quot;);
      Mono&lt;ReceiveMessageResponse&gt; responseMono = receiveMessage(queueUrl);
      Flux&lt;Message&gt; messages = getItems(responseMono);
      messages.subscribe(message -&gt; disposeOfFlux(message, queueUrl));
  }
  
  protected Flux&lt;Message&gt; getItems(Mono&lt;ReceiveMessageResponse&gt; responseMono) {
     return responseMono.repeat().retry()
              .map(ReceiveMessageResponse::messages)
              .map(Flux::fromIterable)
              .flatMap(messageFlux -&gt; messageFlux);
  
  }
  
  protected void disposeOfFlux(Message message, String queueUrl) {
      log.info(&quot;Inbound SMS Received from SQS with MessageId: {}&quot;, message.messageId());
      if (someConditionIsMet()) 
          deleteMessage(queueUrl, message);
  }
  
  protected Mono&lt;ReceiveMessageResponse&gt; receiveMessage(String queueUrl) {
      return Mono.fromFuture(() -&gt; sqsAsyncClient.receiveMessage(
                      ReceiveMessageRequest.builder()
                              .maxNumberOfMessages(5)
                              .messageAttributeNames(&quot;All&quot;)
                              .queueUrl(queueUrl)
                              .waitTimeSeconds(10)
                              .visibilityTimeout(30)
                              .build()));
  }
  
  protected void deleteMessage(String queueUrl, Message message) {
      sqsAsyncClient.deleteMessage(DeleteMessageRequest.builder()
                      .queueUrl(queueUrl)
                      .receiptHandle(message.receiptHandle())
                      .build())
              .thenAccept(deleteMessageResponse -&gt; log.info(&quot;deleted message with handle {}&quot;, message.receiptHandle()));
  }
  }
  </code></pre>