deep-framework
Version:
145 lines (113 loc) • 3.81 kB
JavaScript
var CLSUtils = require('./utils').CLSUtils;
var logger = require('./logger');
/**
* Capture module.
* @module capture
*/
/**
* Wrap to automatically capture information for the segment.
* @param {string} name - The name of the new subsegment.
* @param {function} fcn - The function conext to wrap.
* @param {Segment|Subsegment} [parent] - The parent for the new subsegment, for manual mode.
* @alias module:capture.capture
*/
var capture = function capture(name, fcn, parent) {
validate(name, fcn);
var current, executeFcn;
var parentSeg = parent ? parent : CLSUtils.getSegment();
if (!parentSeg) {
logger.warn('Param "parent" required for tracing in manual mode.');
return fcn();
}
current = parentSeg.addNewSubsegment(name);
executeFcn = captureFcn(fcn, current);
try {
executeFcn(current);
current.close();
} catch (e) {
current.close(e);
throw(e);
}
};
/**
* Wrap to automatically capture information for the segment/subsegment. You must close the segment
* manually from within the function.
* @param {string} name - The name of the new subsegment.
* @param {function} fcn - The function conext to wrap.
* @param {Segment|Subsegment} [parent] - The parent for the new subsegment, for manual mode.
* @alias module:capture.captureAsync
*/
var captureAsync = function captureAsync(name, fcn, parent) {
validate(name, fcn);
var current, executeFcn;
var parentSeg = parent ? parent : CLSUtils.getSegment();
if (!parentSeg) {
logger.warn('Param "parent" required for tracing in manual mode.');
return fcn();
}
current = parentSeg.addNewSubsegment(name);
executeFcn = captureFcn(fcn, current);
try {
executeFcn(current);
} catch (e) {
current.close(e);
throw(e);
}
};
/**
* Wrap to automatically capture information for the segment/subsegment. This wraps the callback and returns a function.
* when executed, all params are passed through accordingly. An additional argument is appended to gain access to the newly created subsegment.
* For this reason, always call the captured callback with the full list of params.
* @param {string} name - The name of the new subsegment.
* @param {function} fcn - The function conext to wrap.
* @param {Segment|Subsegment} [parent] - The parent for the new subsegment, for manual mode.
* @alias module:capture.captureCallback
*/
var captureCallback = function captureCallback(name, fcn, parent) {
validate(name, fcn);
var base = parent ? parent : CLSUtils.getSegment();
if (!base) {
logger.warn('Param "parent" required for tracing in manual mode.');
return fcn;
}
base.incrementCounter();
return function() {
var parentSeg = parent ? parent : CLSUtils.getSegment();
var args = Array.prototype.slice.call(arguments);
capture(name, fcn.bind.apply(fcn, [null].concat(args)), parentSeg);
base.decrementCounter();
}.bind(this);
};
function captureFcn(fcn, current) {
var executeFcn;
if (CLSUtils.isCLSMode()) {
var session = CLSUtils.getNamespace();
var clsFcn = function() {
var value;
session.run(function() {
CLSUtils.setSegment(current);
value = fcn(current);
});
return value;
};
executeFcn = clsFcn;
} else {
executeFcn = fcn;
}
return executeFcn;
}
function validate(name, fcn) {
var error;
if (!name || typeof name !== 'string') {
error = 'Param "name" must be a non-empty string.';
logger.error(error);
throw new Error(error);
} else if (typeof fcn !== 'function') {
error = 'Param "fcn" must be a function.';
logger.error(error);
throw new Error(error);
}
}
module.exports.capture = capture;
module.exports.captureAsync = captureAsync;
module.exports.captureCallback = captureCallback;