{"id":27334976,"url":"https://github.com/dmuth/another-circuit-breaker","last_synced_at":"2025-04-12T14:46:46.818Z","repository":{"id":15762089,"uuid":"18500923","full_name":"dmuth/another-circuit-breaker","owner":"dmuth","description":"This Node.js module implements the \"Circuit Breaker\" pattern, which is used to detect failures and prevent a failure from occurring regularly. ","archived":false,"fork":false,"pushed_at":"2020-09-03T22:22:26.000Z","size":56,"stargazers_count":1,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-05-02T06:07:17.649Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmuth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-06T22:37:30.000Z","updated_at":"2020-09-03T22:20:53.000Z","dependencies_parsed_at":"2022-09-24T04:01:11.144Z","dependency_job_id":null,"html_url":"https://github.com/dmuth/another-circuit-breaker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fanother-circuit-breaker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fanother-circuit-breaker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fanother-circuit-breaker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fanother-circuit-breaker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmuth","download_url":"https://codeload.github.com/dmuth/another-circuit-breaker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248585248,"owners_count":21128974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-12T14:46:46.097Z","updated_at":"2025-04-12T14:46:46.811Z","avatar_url":"https://github.com/dmuth.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## Circuit Breaker\n\nThis 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.\n\n### The Consequences of undeteted failures\n\nYour 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.\n\n### Installation\n\n`npm install another-circuit-breaker`\n\n\n### Usage\n\n    var circuitBreaker = require(\"another-circuit-breaker\");\n    \n    var options = {\n        timeout: 5,\n        maxFailures: 20,\n        min: 0,\n        decayAlgorithm: \"percent\",\n        decayRate: 10,\n        debug: function(str) { console.log(\"CircuitBreaker:\", str); }\n        };\n    var breaker = new circuitBreaker(options); // Only run this ONCE\n    \n    breaker.go(function(cb) {\n        //\n        // Do your work here, then call cb, optionally with an error.\n        // If there were too many errors, this function will NOT be called.\n        // cb is a callback within circuitBreaker which will handle any errors, then call the next function\n        //\n    \t\n        }, function(error) {\n        //\n        // This is called when we're all done with the circuitBreaker\n        // \n\n        })\n\n#### Options\n\nThe options object can be used to alter the behavior of CircuitBreaker.  These are the options available:\n\n- timeout: Number of seconds after which we'll assume that the first callback timed out, and treat it as an error. (default: 1)\n   - 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.\n- maxFailures: Maximum number of failures before the CircuitBreaker is set to \"open\" (default: 10)\n- min: Minimum number of failures before the CircuitBreaker is set to \"closed\" (default: 0)\n- decayAlgorithm: The decay algorithm plugin to use (default: \"constant\")\n- decayRate: The rate of decay, used in some algorithms (default: 1)\n- 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)\n\n    \n### \"Decaying? What's that?\"\n\nIn 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.\n    \n### Plugins\n\nCircuitBreaker ships with a number of modules included.  Here is the list:\n\n- constant.js - Decay the number of errors at a rate defined by decayRate.  **This is the default, and is generally a good choice.**\n- example.js - Sets the number of errors to 1 on each pass.  Don't use this in production.\n- half.js - Divides the number of errors in half on each pass.  Not very useful except for VERY high traffic scenarios.\n- never.js - Never touch the number of errors. Once the CircuitBreaker is tripped open, it stays open.  Forever. Good for testing.\n- percent.js - Decay the number of errors at the percentage rate defined by decayRate.\n- zero.js - Set the number of errors to zero instantly.  Not useful for anything other than testing.\n\nAny of these can be chosen with the \"decayAlgorithm\" option.\n\n### Writing your own Plugins\n\nExisting plugins can be found in the plugins/ directory.  All plugins have this signature function:\n\n    /**\n    *\n    * @param {object} stats Our stats object\n    * @param {object} options Our options object\n    *    The decay rate can be accessed as options.decayRate\n    * @param {function} debug Our debugging funciton\n    *\n    */\n    function(stats, options, debug)\n\n\nWant 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.\n\n\n#### Development environment\n\nIn 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:\n\n- `Vagrantfile` - Used in conjction with Vagrant to create 3 separate virtual machines: \n   - A \"bad_server\" which periodically takes a long time to reply to queries\n   - A \"good_server\" which accepts HTTP connections and makes HTTP connections to the bad server, and uses CircuitBreaker\n   - A \"client\", which is used to connect to the good server.\n- `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.\n- `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.\n- `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.\n\n##### Installing Node.js on each VM\n\nThe 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:\n\n    sudo add-apt-repository ppa:chris-lea/node.js\n    sudo apt-get update\n    sudo apt-get install python-software-properties python g++ make nodejs\n\n\n### Where to find this project online\n\n- [https://github.com/dmuth/another-circuit-breaker](https://github.com/dmuth/another-circuit-breaker)\n- [https://bitbucket.org/dmuth/another-circuit-breaker](https://bitbucket.org/dmuth/another-circuit-breaker)\n\n\n### Contact\n\nQuestions? Complaints? Here's my contact info: [http://www.dmuth.org/contact](http://www.dmuth.org/contact)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmuth%2Fanother-circuit-breaker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmuth%2Fanother-circuit-breaker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmuth%2Fanother-circuit-breaker/lists"}