Source: measured-core/lib/metrics/Timer.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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`.
 */