npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

re

v0.1.4

Published

Do it again, after a bit.

Downloads

6,801

Readme

Re

Do it again, if it doesn't work the first time. Supports various configurable retry strategies, including: constant, exponential backoff and linear backoff.

Functions are styled to match the simplicity and ease of use found in the async library.

Install

npm install re

Quick Example

var Re = require('re'),
    re = new Re();

re.try(repeatMe, doMeAtTheEnd);

var repeatMe = function(retryCount, done){
  if(retryCount < 2) done(new Error("Not there yet!"));
  else done(null, retryCount);
};

var doMeAtTheEnd = function(err, retryCount){
  console.log("It took this many tries: " + retryCount);
};

In the Browser

Tested in recent versions of Internet Explorer, Firefox and Chrome. Usage:

<script type="text/javascript" src="re.js"></script>
<script type="text/javascript">
  var re = new Re();

  re.try(repeatMe, doMeAtTheEnd);
  
  // repeatMe and doMeAtTheEnd are exactly as above

</script>

Try it in your browser with this test: test/test.html or play with the test in this fiddle: re-fiddle (these pages don't work in IE, because it's recently gone from lax to pedantic).

Usage

If you like the defaults, call it like this:

var Re = require('re'),
    re = new Re();

re.try(function(retryCount, done){
    if(retryCount < 2) done(new Error("Not there yet!"));
    else done(null, retryCount);
  },
  function(err, retryCount){
    console.log("It took this many retries: " + retryCount);
});

The re.try function takes two arguments, a function to call until it works (or we run out of retries) and a function to call when it finally succeeds (or we fail too many times). As the name suggests we automatically wrap your function in a standard try block and, if an exception occurs, call it again according to the retry schedule.

This first function passed to re.try should take 2 arguments like this:

function operation(retryCount, done)

The retryCount argument is the number of the current retry. It'll be zero the first time and get bigger every time.

The done argument is a function to call when you've completed your operation. If you encounter an error condition, pass in the err object as the first argument. If you don't encounter an error, pass in a falsy first argument (null works). If you give us a falsy error and no exception happens, we call your callback with all the arguments passed into this function.

The second function passed to re.try can take as many arguments as you like but should always start with an error parameter. This will be falsy, if no error happens.

The re.do function is like re.try except it doesn't wrap your operation in a try...catch.

Options

The default options look like this:

var options = {
    retries : 10,
    strategy : {
      "type": Re.STRATEGIES.EXPONENTIAL,
      "initial":100,
      "base":2
    }
}

You pass this options object into the Re constructor.

var Re = require('re'),
    re = new Re(options);

This gives you 10 retries and an exponential backoff strategy with the following progression (in milliseconds): 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200

Retry Strategy Examples

The following will retry every 400 milliseconds:

{"type": Re.STRATEGIES.CONSTANT, "initial": 400}

The following will give a linear backoff strategy that has the following progression (when paired with retries: 10) : 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 1800

{"type": Re.STRATEGIES.LINEAR, "initial": 200, "max":1800}

Both progressive strategies accept the max option. All strategies also accept a rand option. This is a Boolean that adds a random multiplier between 1 and 2. This makes them act like the tradition backoff function. This option is set to false by default.

Stability

Test coverage is good and expanding. We use mocha.

Technical Details

The traditional exponential backoff function is described here: Exponential Backoff in Distributed Systems. This is equivalent to our exponential backoff function with the rand option set to true.

Our formula for exponential backoff looks something like this, when using all the options:

return Math.min(random * initial * Math.pow(base, retry), max);

Where random is a random number in the half-open interval [1, 2). When randomness is turned off, the value of this variable is always 1.

If you don't specify the max option, the formula looks like this:

return random * initial * Math.pow(base, retry);

I'm shamelessly stealing the following link from node-retry just because it's fun for nerdy math people to play with. You can use it to calculate the exact value you need for the base option so that all retry intervals sum to a desired amount: Wolfram Alpha.