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

another-circuit-breaker

v0.3.4

Published

An implementation of the Circuit Breaker pattern in Node.js, now with plugin support!

Downloads

85

Readme

Circuit Breaker

This module implements the "Circuit Breaker" pattern, which is used to detect failures and prevent a failure from occurring regularly. A perfect example would be a third-party web service (say, Facebook Graph…) which may perform poorly from time to time, and is completely out of your control.

The Consequences of undeteted failures

Your app will crash. If you're lucky. If you're not lucky, you'll run out of file descriptors and other file or network-based operations in your program will be affected. If you're really unlucky, you'll start hitting the swap space and then run out of RAM, thus ~~unleashing Zalgo~~ the OOM killer which then might kill syslog or worse? You don't want to be there.

Installation

npm install another-circuit-breaker

Usage

var circuitBreaker = require("another-circuit-breaker");

var options = {
    timeout: 5,
    maxFailures: 20,
    min: 0,
    decayAlgorithm: "percent",
    decayRate: 10,
    debug: function(str) { console.log("CircuitBreaker:", str); }
    };
var breaker = new circuitBreaker(options); // Only run this ONCE

breaker.go(function(cb) {
    //
    // Do your work here, then call cb, optionally with an error.
    // If there were too many errors, this function will NOT be called.
    // cb is a callback within circuitBreaker which will handle any errors, then call the next function
    //
	
    }, function(error) {
    //
    // This is called when we're all done with the circuitBreaker
    // 

    })

Options

The options object can be used to alter the behavior of CircuitBreaker. These are the options available:

  • timeout: Number of seconds after which we'll assume that the first callback timed out, and treat it as an error. (default: 1)

    • Note that there is logic to prevent the callback from being called after the timeout callback is fired in the event of a very slow repsonse time.
  • maxFailures: Maximum number of failures before the CircuitBreaker is set to "open" (default: 10)

  • min: Minimum number of failures before the CircuitBreaker is set to "closed" (default: 0)

  • decayAlgorithm: The decay algorithm plugin to use (default: "constant")

  • decayRate: The rate of decay, used in some algorithms (default: 1)

  • debug: Set to true to see debug messages printed out once every second. Set to a function and the function will be called once every second instead. (default: false)

"Decaying? What's that?"

In this context, "decaying" means to lower the number of errors stored in CircuitBreaker every second. This is done so that once a service has thrown errors or timed out too many times, a certain "cooling off period" is enforced, based on the number of errors caught.

Plugins

CircuitBreaker ships with a number of modules included. Here is the list:

  • constant.js - Decay the number of errors at a rate defined by decayRate. This is the default, and is generally a good choice.
  • example.js - Sets the number of errors to 1 on each pass. Don't use this in production.
  • half.js - Divides the number of errors in half on each pass. Not very useful except for VERY high traffic scenarios.
  • never.js - Never touch the number of errors. Once the CircuitBreaker is tripped open, it stays open. Forever. Good for testing.
  • percent.js - Decay the number of errors at the percentage rate defined by decayRate.
  • zero.js - Set the number of errors to zero instantly. Not useful for anything other than testing.

Any of these can be chosen with the "decayAlgorithm" option.

Writing your own Plugins

Existing plugins can be found in the plugins/ directory. All plugins have this signature function:

/**
*
* @param {object} stats Our stats object
* @param {object} options Our options object
*    The decay rate can be accessed as options.decayRate
* @param {function} debug Our debugging funciton
*
*/
function(stats, options, debug)

Want to write a plugin? Start by looking in the file example.js. Documentation for the stats system can be found there. Next, make a copy of that file and start writing your plugin. Be sure to make liberal use of the development environemnt (described below) and the debug function.

Development environment

In order to create scenarios under which CircuitBreaker will be the most useful, I took the liberty of creating a development environment. That consists of the following files:

  • Vagrantfile - Used in conjction with Vagrant to create 3 separate virtual machines:
    • A "bad_server" which periodically takes a long time to reply to queries
    • A "good_server" which accepts HTTP connections and makes HTTP connections to the bad server, and uses CircuitBreaker
    • A "client", which is used to connect to the good server.
  • bin/bad_server.sh - To be run on the "bad server" VM, it starts up the node.js server app. Run with -h for options. By default, the server toggles between "good" and "bad" states every 5 seconds. During a "bad" state, the server waits 5000 ms before replying to a query. This simulates a web service with excessive delays.
  • bin/good_server.sh - To be run on the "good server" VM, it starts up the good server app. Run with -h for options, such as which CircuitBreaker decay plugin to test.
  • bin/client.sh - To be run on the "client" VM, it makes connections to the good server in parallel, to simulate lots of incoming connections from the outside world. Run with -h for options, such as the concurrency level and total number of connections to make.
Installing Node.js on each VM

The latest version of Node.js can be installed on each VM by SSHing in (vagrant ssh (bad_server|good_server|client)) and running these commands as root:

sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install python-software-properties python g++ make nodejs

Where to find this project online

Contact

Questions? Complaints? Here's my contact info: http://www.dmuth.org/contact