Your coworkers, mentors and heroes write faulty code. You write faulty code.
Fault Tolerance reduces the impact problems have on your app. At worst you’ll have a bottleneck in a component, but it won’t bring everything else to a grinding halt, or worse yet, send it to the big farm in the cloud.
You definitely don’t need one but a framework makes it really easy to start making things more fault-tolerant while providing a common platform for building, sharing ideas and tools the same way Express.js does for writing web servers.
While making your app more fault-tolerance is very rewarding, it is a VERY HARD THING™.
This is just the tip of the iceberg of concerns introduced by trying to be fault-tolerance.
Supe helps by providing good default solutions for these problems and allows you to modify (or overwrite) any particular one so you can implement the solution that works best for your specific challenge.
npm install --save supe
The first step to fault-tolerance is breaking your app into separate parts.
For example, instead of one file with multiple responsibilities like:
// inside app.jsvar http =db =ws = ;
We're moving towards separate programs with individual responsibilities and the app becomes their manager / coordinator.
// inside app.jsvar http = supervisorstart 'http' 'http.js'db = supervisorstart 'db' 'db-driver.js'ws = supervisorstart 'ws' 'websocket.js';
Supe refers to the manager / coordinator as a supervisor; the components are called citizens.
var supervisor = ;
// supervise server.jssupervisor;supervisorstart 'server ';// orsupervisorstart 'server' 'server.js' ;// supervisor will restart server.js whenever it crashes
NOTE: Supe will stop reviving a citizen after it crashes excessively.
var supervisor =server = supervisorstart 'server' 'server.js' retries: 3 duration: 3 ;// if server.js crashes more than three times in three minutes, supe considers it overcrashed
var supervisor = retries: 3 duration: 3server = supervisorstart 'server' 'server.js'worker = supervisorstart 'worker' 'worker.js' ;// all supervised scripts will use the default overcrash thresholds// individual overcrash thresholds override defaultsvar worker2 = supervisorstart 'worker2' 'worker.js' retries: 20worker3 = supervisorstart 'worker3' 'worker.js' duration: 1 ;
Supe uses cjs-noticeboard to send out notices when certain actions happen. This makes it easy to extend Supe to build custom behavior for your supervisor.
All you need to do is watch a relevant notice and your code will be executed every time a notice is sent out.
// tell pagerduty component to send alert when component crashes excessivelysupervisornoticeboard;
Mail is a simple yet reliable way to communicate between components. With a few lines of code, you can send some data to a citizen. When the citizen starts receiving data, hopefully they'll know what to do with what you sent.
Mail is more reliable than notices because they are stored on the supervisor regardless of citizen's state. When the citizen is ready to receive mail, they're sent in the same order they were received by the supervisor.
// inside citizenvar supe = ;// to supervisorsupemail;// to other citizensupemail;
// inside citizenvar supe = ;supemail;
Messages don't have to be strings.
// inside server.jssupemail;
Supervised scripts are given one message at a time.
No more messages will be sent til the current one is acknowledged ( ack() ).
Once you acknowledge a message, the next message is automatically sent.
// worker onefor var x = 1; x <= 100; x += 1supemail;// worker twofor var x = 100; x >= 1; x -= 1supemail;// worker threesupemail;// worker1 says 1// worker2 says 100// worker1 says 2// worker2 says 99// worker1 says 3// worker2 says 98// worker1 says 4// worker2 says 97
Supervised scripts can supervise other scripts.
// inside supervisor.jsvar supervisor = ;supervisorstart 'worker' 'worker.js' ;// inside worker.jsvar supe =supervisor = ;supervisorstart 'subworker' 'sub-worker.js' ;if supesupervised supemail;