From bd7bbdd076bb4cf83a6fe714d7b25464ddcb8ade Mon Sep 17 00:00:00 2001 From: vmarchaud Date: Sat, 28 Mar 2020 12:05:58 +0100 Subject: [PATCH] fix(plugin-express): fix double span end #908 --- .../src/express.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/opentelemetry-plugin-express/src/express.ts b/packages/opentelemetry-plugin-express/src/express.ts index fc310acd477..c505e80463c 100644 --- a/packages/opentelemetry-plugin-express/src/express.ts +++ b/packages/opentelemetry-plugin-express/src/express.ts @@ -221,19 +221,21 @@ export class ExpressPlugin extends BasePlugin { * - however it will not represent the actual time that the span took * - we would need to hook into the http response's `end` event. * - * The fix for case 4) is to hook into the `end` event, but it would apply - * to case 2) and 3), which would cost quite a lot of memory for big express apps. - * - * The workaround is to schedule a callback to run on next tick and check if the - * callback has been called. If not we close the span because we assume being - * in the case 2) or 4). + * The workaround is to schedule a callback to run on next tick which + * would ensure that the layer was async, and then add a listener on the + * 'end' event to end the span. */ const result = original.apply(this, arguments); setImmediate(() => { if (callbackHasBeenCalled === false) { - span.end(); + res.once('end', function() { + // its possible that the layer was async but called its callback + // between the setImmediate and the response was sent to the client + if (callbackHasBeenCalled === true) return; + span.end(); + }); } - }); + }).unref(); return result; }; });