From 1ad7566f0c131a8fc110b979a2f2cf31b5a375a3 Mon Sep 17 00:00:00 2001 From: Glen Keane Date: Tue, 11 Jun 2019 20:07:44 +0100 Subject: [PATCH] add ability to get response time on reply (#1697) * add ability to get response time on reply * feedback * Update docs/Reply.md as per suggestion Co-Authored-By: Manuel Spigolon * update type of FastifyReply * add type test --- docs/Reply.md | 9 +++++++++ fastify.d.ts | 1 + lib/reply.js | 15 +++++++++++---- test/internals/reply.test.js | 30 +++++++++++++++++++++++++++++- test/types/index.ts | 4 ++++ 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/docs/Reply.md b/docs/Reply.md index 5792d2eb03..e1b92e91a1 100644 --- a/docs/Reply.md +++ b/docs/Reply.md @@ -10,6 +10,7 @@ - [.hasHeader(key)](#hasheaderkey) - [.redirect(dest)](#redirectdest) - [.callNotFound()](#callnotfound) + - [.getResponseTime()](#getresponsetime) - [.type(contentType)](#typecontenttype) - [.serializer(func)](#serializerfunc) - [.sent](#sent) @@ -109,6 +110,14 @@ Invokes the custom not found handler. reply.callNotFound() ``` + +### .getResponseTime() +Invokes the custom response time getter to calculate the amount of time passed since the request was started. + +```js +const milliseconds = reply.getResponseTime() +``` + ### .type(contentType) Sets the content type for the response. diff --git a/fastify.d.ts b/fastify.d.ts index 025406598b..f74a54ed67 100644 --- a/fastify.d.ts +++ b/fastify.d.ts @@ -166,6 +166,7 @@ declare namespace fastify { getHeader(name: string): string | undefined hasHeader(name: string): boolean callNotFound(): void + getResponseTime(): number type(contentType: string): FastifyReply redirect(url: string): FastifyReply redirect(statusCode: number, url: string): FastifyReply diff --git a/lib/reply.js b/lib/reply.js index ca46c6ed4c..02562dd7f1 100644 --- a/lib/reply.js +++ b/lib/reply.js @@ -222,6 +222,16 @@ Reply.prototype.callNotFound = function () { notFound(this) } +Reply.prototype.getResponseTime = function () { + var responseTime = 0 + + if (this[kReplyStartTime] !== undefined) { + responseTime = now() - this[kReplyStartTime] + } + + return responseTime +} + function preserializeHook (reply, payload) { if (reply.context.preSerialization !== null) { onSendHookRunner( @@ -460,11 +470,8 @@ function onResponseCallback (err, request, reply) { if (reply.log[kDisableRequestLogging]) { return } - var responseTime = 0 - if (reply[kReplyStartTime] !== undefined) { - responseTime = now() - reply[kReplyStartTime] - } + var responseTime = reply.getResponseTime() if (err != null) { reply.log.error({ diff --git a/test/internals/reply.test.js b/test/internals/reply.test.js index efa49b66e4..f9f819093c 100644 --- a/test/internals/reply.test.js +++ b/test/internals/reply.test.js @@ -14,7 +14,7 @@ const { } = require('../../lib/symbols') test('Once called, Reply should return an object with methods', t => { - t.plan(12) + t.plan(13) const response = { res: 'res' } function context () {} function request () {} @@ -27,6 +27,7 @@ test('Once called, Reply should return an object with methods', t => { t.is(typeof reply.status, 'function') t.is(typeof reply.header, 'function') t.is(typeof reply.serialize, 'function') + t.is(typeof reply.getResponseTime, 'function') t.is(typeof reply[kReplyHeaders], 'object') t.strictEqual(reply.res, response) t.strictEqual(reply.context, context) @@ -977,3 +978,30 @@ test('should throw error when attempting to set reply.sent more than once', t => t.pass() }) }) + +test('reply.getResponseTime() should return 0 before the timer is initialised on the reply by setting up response listeners', t => { + t.plan(1) + const response = { statusCode: 200 } + const context = {} + const reply = new Reply(response, context, null) + t.equal(reply.getResponseTime(), 0) +}) + +test('reply.getResponseTime() should return a number greater than 0 after the timer is initialised on the reply by setting up response listeners', t => { + t.plan(1) + const fastify = require('../..')() + fastify.route({ + method: 'GET', + url: '/', + handler: (req, reply) => { + reply.send('hello world') + } + }) + + fastify.addHook('onResponse', (req, reply) => { + t.true(reply.getResponseTime() > 0) + t.end() + }) + + fastify.inject({ method: 'GET', url: '/' }) +}) diff --git a/test/types/index.ts b/test/types/index.ts index 34472b2551..c250633300 100644 --- a/test/types/index.ts +++ b/test/types/index.ts @@ -346,6 +346,10 @@ server .get('/deprecatedpath/*', (req, reply) => { reply.callNotFound() }) + .get('/getResponseTime', function (req, reply) { + const milliseconds : number = reply.getResponseTime() + reply.send({ milliseconds }) + }) // Generics example interface Query {