From 90f2269276fdec71aac7be30b0f1e6603d27659c Mon Sep 17 00:00:00 2001 From: Chris Matheson Date: Thu, 26 Jul 2018 14:17:44 +0100 Subject: [PATCH 1/4] introduction of function which understands async return and instruments appropriately --- lib/statsFunctions.js | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/statsFunctions.js b/lib/statsFunctions.js index 6a667470..bd5bd947 100644 --- a/lib/statsFunctions.js +++ b/lib/statsFunctions.js @@ -48,6 +48,42 @@ function applyStatsFns (Client) { }; }; + /** + * Decorates an async function with timing recording behaviour. + * + * This version of `timer` will record the time take for the asyncronus action returned by `func` + * not just the execution time of `func` itself. + * + * @param func {(...A):Promise} The function to run + * @param stat {String|Array} The stat(s) to send + * @param sampleRate {Number=} The Number of times to sample (0 to 1). Optional. + * @param tags {Array=} The Array of tags to add to metrics. Optional. + * @param callback {Function=} Callback when message is done being delivered. Optional. + */ + Client.prototype.asyncTimer = function (func, stat, sampleRate, tags, callback) { + var self = this; + return function() { + var end = hrtimer(); + var p = func.apply(null, arguments); + var recordStat = () => self.timing(stat, end(), sampleRate, tags, callback); + + return p.then(recordStat, recordStat); + }; + }; + + function hrtimer() { + var start = process.hrtime(); + + return function () { + var durationComponents = process.hrtime(start); + var seconds = durationComponents[0]; + var nanoseconds = durationComponents[1]; + var duration = seconds * 1000 + nanoseconds / 1E6; + return duration; + }; + } + + /** * Increments a stat by a specified amount * @param stat {String|Array} The stat(s) to send @@ -267,4 +303,4 @@ function applyStatsFns (Client) { }; } -module.exports = applyStatsFns; \ No newline at end of file +module.exports = applyStatsFns; From fdf9a9c903d74c87edb3d4eccd2f2c9a269a3ba9 Mon Sep 17 00:00:00 2001 From: Chris Matheson Date: Thu, 26 Jul 2018 14:34:37 +0100 Subject: [PATCH 2/4] adding tests (should have done sooner as it wasnt working) --- lib/statsFunctions.js | 2 +- test/timer.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/statsFunctions.js b/lib/statsFunctions.js index bd5bd947..36228d5c 100644 --- a/lib/statsFunctions.js +++ b/lib/statsFunctions.js @@ -65,7 +65,7 @@ function applyStatsFns (Client) { return function() { var end = hrtimer(); var p = func.apply(null, arguments); - var recordStat = () => self.timing(stat, end(), sampleRate, tags, callback); + var recordStat = function() { self.timing(stat, end(), sampleRate, tags, callback); }; return p.then(recordStat, recordStat); }; diff --git a/test/timer.js b/test/timer.js index d3813280..8fdcb1df 100644 --- a/test/timer.js +++ b/test/timer.js @@ -1,5 +1,5 @@ 'use strict'; - +var StatsD = require('../lib/statsd'); var assert = require('assert'); var createStatsdClient = require('./helpers').createStatsdClient; @@ -105,5 +105,32 @@ module.exports = function runTimerTestSuite() { }); }); }); + + it('should record "user time" of promise', function () { + /* globals Promise */ + var statsd = new StatsD({mock:true}); + + var onehundredMsFunc = function () { return delay(100); }; + + var instrumented = statsd.asyncTimer(onehundredMsFunc, 'name-thingy'); + + return instrumented().then(function() { + + var stat = statsd.mockBuffer[0]; + var name = stat.split(/:|\|/)[0]; + var time = stat.split(/:|\|/)[1]; + + assert.equal(name, 'name-thingy'); + assert.ok(parseFloat(time) >= 100); + assert.ok(parseFloat(time) < 110); + }); + }); }); }; + + +function delay(n) { + return new Promise(function (resolve, reject) { + setTimeout(resolve, n); + }); +} From 5d1f7eb0c9f1a3242109d4eb85e9beb1feef77fd Mon Sep 17 00:00:00 2001 From: Chris Matheson Date: Thu, 26 Jul 2018 16:00:10 +0100 Subject: [PATCH 3/4] whoops, actually return the correct promise --- lib/statsFunctions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/statsFunctions.js b/lib/statsFunctions.js index 36228d5c..bd82a2b9 100644 --- a/lib/statsFunctions.js +++ b/lib/statsFunctions.js @@ -66,8 +66,8 @@ function applyStatsFns (Client) { var end = hrtimer(); var p = func.apply(null, arguments); var recordStat = function() { self.timing(stat, end(), sampleRate, tags, callback); }; - - return p.then(recordStat, recordStat); + p.then(recordStat, recordStat); + return p; }; }; From c8ea82212c6b95d1f086286051be4b2bf4cd9a1b Mon Sep 17 00:00:00 2001 From: Chris Matheson Date: Fri, 27 Jul 2018 08:50:51 +0100 Subject: [PATCH 4/4] raise upper theshold of sanity check (review feedback) --- test/timer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/timer.js b/test/timer.js index 8fdcb1df..24cae592 100644 --- a/test/timer.js +++ b/test/timer.js @@ -122,7 +122,7 @@ module.exports = function runTimerTestSuite() { assert.equal(name, 'name-thingy'); assert.ok(parseFloat(time) >= 100); - assert.ok(parseFloat(time) < 110); + assert.ok(parseFloat(time) < 200); }); }); });