title: Amazon SQS with aws-sdk receiveMessage Stall
body: <p>I'm using the aws-sdk node module with the (as far as I can tell) approved way to poll for messages.</p>
  
  <p>Which basically sums up to:</p>
  
  <pre><code>        sqs.receiveMessage({
              QueueUrl: queueUrl,
              MaxNumberOfMessages: 10,
              WaitTimeSeconds: 20
          }, function(err, data) {
              if (err) {
                  logger.fatal('Error on Message Recieve');
                  logger.fatal(err);
              } else {
                  // all good
                  if (undefined === data.Messages) {
                      logger.info('No Messages Object');
                  } else if (data.Messages.length &gt; 0) {
                      logger.info('Messages Count: ' + data.Messages.length);
  
                      var delete_batch = new Array();
                      for (var x=0;x&lt;data.Messages.length;x++) {
                          // process
                          receiveMessage(data.Messages[x]);
  
                          // flag to delete
  
                          var pck = new Array();
                          pck['Id'] = data.Messages[x].MessageId;
                          pck['ReceiptHandle'] = data.Messages[x].ReceiptHandle;
  
                          delete_batch.push(pck);
                      }
  
                      if (delete_batch.length &gt; 0) {
                          logger.info('Calling Delete');
                          sqs.deleteMessageBatch({
                              Entries: delete_batch,
                              QueueUrl: queueUrl
                          }, function(err, data) {
                              if (err) {
                                  logger.fatal('Failed to delete messages');
                                  logger.fatal(err);
                              } else {
                                  logger.debug('Deleted recieved ok');
                              }
                          });
                      }
                  } else {
                      logger.info('No Messages Count');
                  }
              }
          });
  </code></pre>
  
  <p><code>receiveMessage</code> is my "do stuff with collected messages if I have enough collected messages" function</p>
  
  <p>Occasionally, my script is stalling because I don't get a response for Amazon at all, say for example there are no messages in the queue to consume and instead of hitting the WaitTimeSeconds and sending a "no messages object", the callback isn't called.</p>
  
  <p>(I'm writing this up to Amazon Weirdness)</p>
  
  <p>What I'm asking is whats the best way to detect and deal with this, as I have some code in place to stop concurrent calls to receiveMessage.</p>
  
  <p>The suggested answer here: <a href="https://stackoverflow.com/questions/17716401/nodejs-sqs-queue-processor">Nodejs sqs queue processor</a> also has code that prevents concurrent message request queries (granted it's only fetching one message a time)</p>
  
  <p>I do have the whole thing wrapped in </p>
  
  <pre><code>var running = false;
  runMonitorJob = setInterval(function() {
      if (running) {
      } else {
          running = true;
          // call SQS.receive
      }
  }, 500);
  </code></pre>
  
  <p>(With a running = false after the delete loop (not in it's callback))</p>
  
  <p>My solution would be</p>
  
  <pre><code>watchdogTimeout = setTimeout(function() {
      running = false;
  }, 30000);
  </code></pre>
  
  <p>But surely this would leave a pile of floating sqs.receive's lurking about and thus much memory over time?</p>
  
  <p>(This job runs all the time, and I left it running on Friday, it stalled Saturday morning and hung till I manually restarted the job this morning)</p>
  
  <p>Edit: I have seen cases where it hangs for ~5 minutes and then suddenly gets messages <em>BUT</em> with a wait time of 20 seconds it should throw a "no messages" after 20 seconds. So a WatchDog of ~10 minutes might be more practical (depending on the rest of ones business logic)</p>
  
  <p>Edit: Yes Long Polling is already configured Queue Side.</p>
  
  <p>Edit: This is under (latest) v2.3.9 of <a href="https://github.com/aws/aws-sdk-js" rel="nofollow noreferrer">aws-sdk</a> and NodeJS v4.4.4</p>