Skip to content

Commit

Permalink
Implement promise status object-based monitoring
Browse files Browse the repository at this point in the history
  • Loading branch information
briancavalier committed Jun 30, 2013
1 parent bcb90e0 commit eac553e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 57 deletions.
84 changes: 43 additions & 41 deletions monitor/aggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,59 @@ define(function() {
return function createAggregator(reporter) {
var promises, nextKey;

nextKey = 0;
function Monitor(parent) {
if(!(this instanceof Monitor)) {
return new Monitor(parent);
}

var stackHolder;

try {
throw new Error();
} catch(e) {
stackHolder = e;
}

function Monitor(key) {
this.key = key;
this.key = nextKey++;
this.parent = parent;
this.timestamp = +(new Date());
this.createdAt = stackHolder;
}

Monitor.prototype = {
observed: function () {
delete promises[this.key];
this._observed = true;

if(this.key in promises) {
delete promises[this.key];
report();
}

return new Monitor(this);
},
fulfilled: function () {
delete promises[this.key];
report();
if(this.key in promises) {
report();
}
},
rejected: function (reason) {
var stackHolder, rec;

rec = promises[this.key];
var stackHolder;

if (rec) {
try {
throw new Error(reason && reason.message || reason);
} catch (e) {
stackHolder = e;
}
if(this._observed) {
return;
}

rec.reason = reason;
rec.rejectedAt = stackHolder;
promises[this.key] = this;

report();
try {
throw new Error(reason && reason.message || reason);
} catch (e) {
stackHolder = e;
}

this.reason = reason;
this.rejectedAt = stackHolder;
report();
}
};

Expand All @@ -52,39 +74,19 @@ define(function() {
return publish({ publish: publish });

function publish(target) {
target.monitorPromise = monitorPromise;
target.PromiseStatus = Monitor;
target.reportUnhandled = report;
target.resetUnhandled = reset;
return target;
}

function monitorPromise(parentKey) {
var stackHolder, key;

try {
throw new Error();
} catch(e) {
stackHolder = e;
}

key = nextKey++;

promises[key] = {
key: key,
timestamp: +(new Date()),
createdAt: stackHolder,
parent: promises[parentKey]
};

return new Monitor(key);
}

function report() {
return reporter(promises);
}

function reset() {
promises = {};
nextKey = 0;
promises = {}; // Should be WeakMap
}
};

Expand Down
24 changes: 8 additions & 16 deletions when.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,28 +225,24 @@ define(function () {
* @returns {Promise} promise whose fate is determine by resolver
*/
function promise(resolver) {
return _promise(resolver);
return _promise(resolver, monitorApi.PromiseStatus && monitorApi.PromiseStatus());
}

/**
* Creates a new promise, linked to parent, whose fate is determined
* by resolver.
* @param {function} resolver function(resolve, reject, notify)
* @param {Promise?} parent promise from which the new promise is begotten
* @param {Promise?} status promise from which the new promise is begotten
* @returns {Promise} promise whose fate is determine by resolver
* @private
*/
function _promise(resolver, parent) {
var self, value, monitor, handlers = [];
function _promise(resolver, status) {
var self, value, handlers = [];

self = new Promise(then, inspect);

// Call the provider resolver to seal the promise's fate
try {
if(monitorApi.monitorPromise) {
monitor = monitorApi.monitorPromise(parent);
}

resolver(promiseResolve, promiseReject, promiseNotify);
} catch(e) {
promiseReject(e);
Expand All @@ -273,11 +269,7 @@ define(function () {
.then(resolve, reject, notify);
}

}, monitor && monitor.key);

if (monitor) {
monitor.observed();
}
}, status && status.observed());

return next;
}
Expand All @@ -300,10 +292,10 @@ define(function () {
scheduleHandlers(handlers, value);
handlers = undef;

if (monitor) {
if (status) {
value.then(
function () { monitor.fulfilled(); },
function(r) { monitor.rejected(r); }
function () { status.fulfilled(); },
function(r) { status.rejected(r); }
);
}
}
Expand Down

0 comments on commit eac553e

Please sign in to comment.