delivered in real-time. ! Introduce a web based “subscriber” modeled after message push. ! But instead of delivering individual messages – deliver the aggregated analytic results. ! Highly useful for executive dashboards, retail analytics, mobile real-time updates and many more.
database implemented entirely in node.js. ! Documents are inserted via REST API. ! Analytics are made available via map/reduce. ! When data changes, queries are updated in real- time and subscribers are updated immediately using HTML5 server-sent events.
aggregate Sorting/filter Apply user specific filter/ function Note: RTDB will perform an “incremental” map/ reduce when possible. This is very powerful. Add one record to a million record collection? No need to “remap” the entire dataset.
Sent Events. ! As the prototype matured into an application, the application never outgrew node.js. ! node.js is interpreted so the map/reduce scripts can be changed at run- time. ! Very fast; very stable. ! Scalable I/O. Used heavily for files and subscribers. ! Async model is very well-suited for the internal architecture. ! NPM provides an excellent set of API building blocks for rapid assembly. ! Extremely PaaS friendly. (Heroku, Amazon EBS, Modulus, Cloudnode and more).
API and web admin • Jade – templates for web admin • AWS-SDK – access to the S3 file system • Async – concurrency framework • Symmetry – JSON delta processing • Winston – logging Note: NPM offers several overlapping APIs. You are free to choose the best fit for your needs.
of backing stores; even other databases. • Loads all javascript modules in specified directory via “requires” var cfslist = fs.readdirSync('./cfs'); var cfsTypes = {}; cfslist.forEach(function(file) { var cfs = require('./cfs/' + file); cfsTypes[cfs.name] = cfs; }); self.cfs = new cfsTypes[self.globalSettings.cfs](); self.cfs.init(self.globalSettings.cfsinit);
name() - return a unique name for this provider function init(parms) - initialize with params from settings.json function exists(dir, callback) - does this exist? function get(key, callback) - return object by key function del(key, callback) - delete object by key function put(prefix, item, callback, expires) - put object function list(prefix, callback) - list objects
documents. app.post('/db/collections/:id/documents', function(req, res) { var c = database.collectionAt(req.params.id); var docs = []; if (!Array.isArray(req.body)) docs.push(req.body); else docs = req.body; c.put(docs, function(err) { if (!err) res.send(201); else res.send(500,err); }); }); Note: REST and JSON make it very easy to interact with the database using command line tools such as CURL.
= new events.EventEmitter(); • Register reduce function _emitter.once('change', doReduce); • When there is work… emitter.emit('change'); • Use “once” versus “on” to manage flow.
parallel • Async.eachSeries – process sequentially • Load collections in priority order • Async.eachLimit – parallel, but with limit • Load files from file system without running out of system resources