Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to change retry() params from the task? #1001

Closed
eexit opened this issue Jan 6, 2016 · 5 comments
Closed

Ability to change retry() params from the task? #1001

eexit opened this issue Jan 6, 2016 · 5 comments

Comments

@eexit
Copy link

eexit commented Jan 6, 2016

Hello,

I would like to know if it'd be possible to be able to update the times argument of the retry() from the task?
For instance, I would like to be able to increase the interval value as the attempt count increases or trim down the attempt count to 0 when a particular error occurred (in order to avoid unnecessary doomed attempts).

Example:

var opts = {
    times: 3,
    interval: 500
};

async.retry(opts, function (callback) {
    someCall(function(err) {
        if (err) {
            switch (err.code) {
                case 'Code1':
                    opts.interval += 500; // Increases the interval for next attempt
                    return callback(err);
                case 'Code2':
                    opts.times = 0; // Avoid other attempts
                    return callback(err);
                default:
                    return callback(err);
            }
        }

        callback();
    });
}, function (err) {
    // Some code
});

Any idea or workaround?

Thanks,

@aearly
Copy link
Collaborator

aearly commented Jan 7, 2016

Unfortunately, there's no way to change the retry options after the fact right now -- we copy the options to a new object internally.

To exit early, you could callback with a null error, and some sort of sentinel object you handle specially, but it's kind of a hack.

I'd love to think of a clean way to support customizing the times and interval -- perhaps a function that is called for each iteration to get the times/interval. This would more easily enable things like exponential backoff and early exits.

function getNextInterval(prevInterval, remaningTimes, lastError) {
  if (prevInterval == null) {
    // initial iteration
    return {
      interval: 100,
      times: 5
    };   
  }
  if (lastError && lastError.code === "foo") {
    // exit early
    return {
      times: 0
    };
  }
  // exponential backoff
  return {
    interval: lastInterval * 2,
    times: times - 1
  };
}

async.times(getNextInterval, worker, done);

@eexit
Copy link
Author

eexit commented Jan 25, 2016

Thanks @aearly! I'll try this eventually and see how it behaves...

@murdockcrc
Copy link

Could we implement the interval parameter to support an array of ints? These ints will be used when the attempts array gets built with the timeout functions that provide the execution delay between retries. I know it does not solve the original request (to change the parameters on the fly), but I am working under the assumption that you don't necessarily need to decide the retry backoff times at runtime.

Obviously, if the passed parameter for interval is not an array but an Int, then we use that as the timeout for all the retries.

@aearly
Copy link
Collaborator

aearly commented May 12, 2016

Hmmn, perhaps we could make the retry opts more polymorphic -- if you pass an array for the interval, it uses those numbers for each delay interval in sequence.

@aearly
Copy link
Collaborator

aearly commented Jun 9, 2016

I think the behavior added in #1161 should be good enough for now.

@aearly aearly closed this as completed Jun 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants