UNPKG

scientist

Version:

Carefully refactor critical paths in production

140 lines (121 loc) 3.8 kB
var Measurement, Observation, Promise, _, inspect, slice = [].slice; _ = require('underscore'); Promise = require('bluebird'); inspect = require('util').inspect; Measurement = require('./measurement'); Observation = (function() { Observation.withMeasurement = function() { var args, measure, mixin, observation; measure = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; mixin = _.create(this.prototype, { measure: measure }); observation = _.create(mixin); this.apply(observation, args); return observation; }; function Observation(name, block, options) { var ref; if (options == null) { options = {}; } this.name = name; this._options = options; this.startTime = (ref = options.startTime) != null ? ref : new Date(); this._time = this.measure((function(_this) { return function() { var error, error1; try { return _this.value = block(); } catch (error1) { error = error1; return _this.error = error; } }; })(this)); this.duration = this._time.elapsed; Object.freeze(this); } Observation.prototype.measure = Measurement.benchmark; Observation.prototype.evaluation = function() { if (this.didReturn()) { return this.value; } else { throw this.error; } }; Observation.prototype.settle = function() { return Promise["try"](this.evaluation.bind(this)).reflect().then((function(_this) { return function(inspection) { if (inspection.isFulfilled()) { return function() { return inspection.value(); }; } else { return function() { throw inspection.reason(); }; } }; })(this)).then((function(_this) { return function(block) { return Observation.withMeasurement(_this._time.remeasure.bind(_this._time), _this.name, block, _.defaults({ startTime: _this.startTime }, _this._options)); }; })(this)); }; Observation.prototype.map = function(f) { var block; if (this.didReturn()) { block = _.constant(f(this.value)); return Observation.withMeasurement(this._time.preserve.bind(this._time), this.name, block, _.defaults({ startTime: this.startTime }, this._options)); } else { return this; } }; Observation.prototype.didReturn = function() { return this.error == null; }; Observation.prototype.ignores = function(other) { if (!(other instanceof Observation)) { return false; } if (_.isEmpty(this._options.ignorers)) { return false; } return _.any(this._options.ignorers, (function(_this) { return function(predicate) { return predicate(_this, other); }; })(this)); }; Observation.prototype.matches = function(other) { if (!(other instanceof Observation)) { return false; } if (this.didReturn() && other.didReturn()) { return Boolean(this._options.comparator(this.value, other.value)); } if (!this.didReturn() && !other.didReturn()) { return this._compareErrors(this.error, other.error); } return false; }; Observation.prototype._compareErrors = function(a, b) { return (a.constructor === b.constructor) && _.isEqual(a.message, b.message); }; Observation.prototype.inspect = function(depth, options) { var ref; if (this.didReturn()) { return "value: " + (inspect(this._options.cleaner(this.value), options)); } else { return "error: [" + ((ref = this.error.constructor) != null ? ref.name : void 0) + "] " + (inspect(this.error.message, options)); } }; return Observation; })(); module.exports = Observation;