Peter Klipfel
Peter Klipfel

Reputation: 5178

Node delay retry requests

I'm trying to retry requests after a failed one. However, I want to delay the request. I haven't been able to make setTimeout work because my function tests the returned json (and it's recursive) and setTimeout doesn't return the return value of the callback.

function makeRequest(req, nextjson, attempts){
  // I'm using a different method here
  get({url: "http://xyz.com", json: nextjson},
    function(err, json2){
      if(err===200){
        return json2
      } else {
        // json2 might be bad, so pass through nextjson
        if(attempts < 5){
          return makeRequest(req, nextjson, attempts+1)
        } else {
          // pass back the bad json if we've exhausted tries
          return json2
        }
      }
   })
}

I want to delay the execution of the recursive call. Also, I'm a bit embarrassed by this code. Way too imperative. If you have ways to clean it up, I'd appreciate that too

Upvotes: 0

Views: 2258

Answers (2)

levi
levi

Reputation: 25141

To return a value from the setTimout function, you will have to rewrite your function to utilize callbacks:

function makeRequest(req, nextjson, attempts, callback) {
    // I'm using a different method here
    get({
        url: "http://xyz.com",
        json: nextjson
    }, function (err, json2) {
        if (err === 200 || attempts === 5) {
            callback(json2);
        } else {
            setTimeout(function () {
                makeRequest(req, nextjson, attempts + 1, callback);
            }, 1000);
        }
    });
}

And call it like so:

makeRequest(requestStuff, jsonStuff, 0, function(result){
    // do stuff with result
});

I should add, your get function is an asynchronous function (evident by the callback being passed in), so as it stands, your makeRequest function will never return anything, as the get request will only complete after the makeRequest function has already been executed. You must use callbacks to access the values returned by an asynchronous function.

Upvotes: 2

ali haider
ali haider

Reputation: 20232

I would suggest to try rate limiter for throttling your calls. You will not get a token to move forward if you have breached the limit.

https://github.com/jhurliman/node-rate-limiter

Example:

var RateLimiter = require('limiter').RateLimiter;
// Allow 150 requests per hour. Also understands
// 'second', 'minute', 'day', or a number of milliseconds
var limiter = new RateLimiter(150, 'hour');

// Throttle requests
limiter.removeTokens(1, function(err, remainingRequests) {
  // err will only be set if we request more than the maximum number of
  // requests we set in the constructor

  // remainingRequests tells us how many additional requests could be sent
  // right this moment

  callMyRequestSendingFunction(...);
});

Upvotes: 1

Related Questions