const { MetricTypes } = require('./Metric'); const Histogram = require('./Histogram'); const Meter = require('./Meter'); const Stopwatch = require('../util/Stopwatch'); /** * * Timers are a combination of Meters and Histograms. They measure the rate as well as distribution of scalar events. * <p> * Since they are frequently used for tracking how long certain things take, they expose an API for that: See example 1. * <p> * But you can also use them as generic histograms that also track the rate of events: See example 2. * * @example * var Measured = require('measured') * var timer = new Measured.Timer(); * http.createServer(function(req, res) { * var stopwatch = timer.start(); * req.on('end', function() { * stopwatch.end(); * }); * }); * * * @example * var Measured = require('measured') * var timer = new Measured.Timer(); * http.createServer(function(req, res) { * if (req.headers['content-length']) { * timer.update(parseInt(req.headers['content-length'], 10)); * } * }); * * @implements {Metric} */ class Timer { /** * @param {TimerProperties} [properties] See {@link TimerProperties}. */ constructor(properties) { properties = properties || {}; this._meter = properties.meter || new Meter({}); this._histogram = properties.histogram || new Histogram({}); this._getTime = properties.getTime; this._keepAlive = !!properties.keepAlive; if (!properties.keepAlive) { this.unref(); } } /** * @return {Stopwatch} Returns a Stopwatch that has been started. */ start() { const self = this; const watch = new Stopwatch({ getTime: this._getTime }); watch.once('end', elapsed => { self.update(elapsed); }); return watch; } /** * Updates the internal histogram with value and marks one event on the internal meter. * @param {number} value */ update(value) { this._meter.mark(); this._histogram.update(value); } /** * Resets all values. Timers initialized with custom options will be reset to the default settings. */ reset() { this._meter.reset(); this._histogram.reset(); } end() { this._meter.end(); } /** * Refs the backing timer again. Idempotent. */ ref() { this._meter.ref(); } /** * Unrefs the backing timer. The meter will not keep the event loop alive. Idempotent. */ unref() { this._meter.unref(); } /** * toJSON output: * * <li> meter: See <a href="#meter">Meter</a>#toJSON output docs above.</li> * <li> histogram: See <a href="#histogram">Histogram</a>#toJSON output docs above.</a></li> * * @return {any} */ toJSON() { return { meter: this._meter.toJSON(), histogram: this._histogram.toJSON() }; } /** * The type of the Metric Impl. {@link MetricTypes}. * @return {string} The type of the Metric Impl. */ getType() { return MetricTypes.TIMER; } } module.exports = Timer; /** * @interface TimerProperties * @typedef TimerProperties * @type {Object} * @property {Meter} meter The internal meter to use. Defaults to a new {@link Meter}. * @property {Histogram} histogram The internal histogram to use. Defaults to a new {@link Histogram}. * @property {function} getTime optional function override for supplying time to the {@link Stopwatch} * @property {boolean} keepAlive Optional flag to unref the associated timer. Defaults to `false`. */