javascript - Asynchronous initialization of express.js (or similar) apps -
consider example: have following express.js
app (see code snippet below). want have 1 persistent connection db, , 1 persistent connection own service (which required async call start) during entire app lifetime. , there few entry points, i.e. 1 can access app not via http protocol. of course, want avoid service initialization code duplication , there several such async-initializing services.
/* app.js */ var app = require('express')(); // set views, use routes, etc. var db = require('monk/mongoose/etc')(...); // happily, it's sync operation var myservice = require('./myservice'); // however, it's possible have several such services myservice.init(function(err, result) { // here initialization process finished! }); module.exports.app = app; /* http_server.js (www entry point) */ var app = require('app'); // create http server app , start listening /* telnet_server.js (other entry point) */ var app = require('app'); // create telnet server app , start listening
in code snippet above, time http (or telnet, or other) server starting, there no guarantee, myservice
has initialized.
so, have somehow reorganize app creation code. stick next solution:
/* app.js */ var app = require('express')(); module.exports.app = app; module.exports.init = function(callback) { var myservice = require('./myservice'); myservice.init(callback); } /* entry_point.js */ var app = require('app'); app.init(function(err) { if (!err) { // create http/telnet/etc server , start listening } });
so, question is: common way initialize services required asynchronous call start?
i've created gist here sample of code use task. (it uses q promise library, modified use other promises lib).
the basic idea describe app backbone sequence of asynchronous initialization steps. each step calls 1 or more async functions , binds result name; startup process progresses next initialization step once values resolved current step, , subsequent steps can access values resolved previous steps. allows dependency order of services , components within app described.
for example, backbone can defined follows:
var app = [ { s1: startservice1 }, { s2: startservice2, s3: startservice3 }, { s4: startservice4 } ]
(note in each step definition, references each function given; start()
function - shown in gist - invoke each function in correct order).
each of startxxx vars function takes single argument, , returns deferred promise, e.g.:
function startservice4( app ) { var s1 = app.s1; var s2 = app.s2; var deferred = q.defer(); // ... start service, async stuff ... return deferred; }
the function's app argument represents configured app backbone, , results previous initialization steps available named properties.
i've used pattern in complicated systems, , find simple, flexible , effective way define system's high level structure.
Comments
Post a Comment