Skip to content

Commit

Permalink
Make it work with async hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
kjarmicki authored and dougwilson committed Feb 20, 2022
1 parent 6cfbc00 commit 9403211
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
15 changes: 15 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ module.exports.isFinished = isFinished

var first = require('ee-first')

var asyncHooks
try {
asyncHooks = require('async_hooks')
} catch (ignored) {
}

/**
* Variables.
* @private
Expand All @@ -43,6 +49,7 @@ var defer = typeof setImmediate === 'function'
*/

function onFinished (msg, listener) {
listener = preserveAsyncContext('OnFinishedListener', listener)
if (isFinished(msg) !== false) {
defer(listener, null, msg)
return msg
Expand Down Expand Up @@ -195,3 +202,11 @@ function patchAssignSocket (res, callback) {
callback(socket)
}
}

function preserveAsyncContext (asyncResourceType, fn) {
if (!asyncHooks) {
return fn
}
var asyncResource = new asyncHooks.AsyncResource(asyncResourceType)
return asyncResource.runInAsyncScope.bind(asyncResource, fn, null)
}
28 changes: 28 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ var http = require('http')
var net = require('net')
var onFinished = require('..')

var describeWhenAsyncHooksAreSupported = describe.skip
try {
var asyncHooks = require('async_hooks')
describeWhenAsyncHooksAreSupported = typeof asyncHooks.AsyncLocalStorage === 'function' ? describe : describe.skip
} catch (ignored) {
}

describe('onFinished(res, listener)', function () {
it('should invoke listener given an unknown object', function (done) {
onFinished({}, done)
Expand Down Expand Up @@ -44,6 +51,27 @@ describe('onFinished(res, listener)', function () {
})
})

describeWhenAsyncHooksAreSupported('when used with async hooks', function () {
it('should maintain async context', function (done) {
var asyncLocalStorage = new asyncHooks.AsyncLocalStorage()
var store = {
contextMaintained: true
}

var server = http.createServer(function (req, res) {
asyncLocalStorage.run(store, function () {
onFinished(res, function () {
assert.strictEqual(asyncLocalStorage.getStore(), store)
done()
})
})
setTimeout(res.end.bind(res), 0)
})

sendGet(server)
})
})

describe('when using keep-alive', function () {
it('should fire for each response', function (done) {
var called = false
Expand Down

0 comments on commit 9403211

Please sign in to comment.