Created
October 7, 2015 18:14
-
-
Save AndreasMadsen/f56bbdbcd18a2c6358f3 to your computer and use it in GitHub Desktop.
HTTP kills handle context in async_wrap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const asyncWrap = process.binding('async_wrap'); | |
const http = require('http'); | |
const fs = require('fs'); | |
// | |
// Track | |
// | |
// 1. Setup a global variable to track the context of the async_hook_init_function | |
let callbackContext = 'root'; | |
process.nextTick(function () { | |
callbackContext = null; | |
}); | |
// 2. Overwrite next tick. If this is not here one loses context. | |
function NextTickWrap() {} | |
const nextTick = process.nextTick; | |
process.nextTick = function () { | |
const handle = new NextTickWrap(); | |
asyncInit.call(handle); | |
const args = Array.from(arguments); | |
const callback = args[0]; | |
args[0] = function () { | |
asyncBefore.call(handle); | |
callback.apply(null, arguments); | |
asyncAfter.call(handle); | |
}; | |
nextTick.apply(process, args); | |
}; | |
asyncWrap.setupHooks(asyncInit, asyncBefore, asyncAfter); | |
asyncWrap.enable(); | |
// 3. The before and after event will maintain the callbackContext variable, | |
// such that we known which callback created which handle objects. | |
function asyncBefore() { | |
callbackContext = this.constructor.name; | |
} | |
function asyncAfter() { | |
callbackContext = null; | |
} | |
// 4. (test part) check that there always is a context | |
function asyncInit(provider, parent) { | |
if (!callbackContext && !parent) { | |
// Errors can't be raised here, so just print | |
fs.writeSync(2, 'ISSUE NO CALLBACK CONTEXT\n'); | |
process.exitCode = 1; | |
} | |
} | |
const server = http.createServer(function (req, res) { | |
res.end('hallo world'); | |
}); | |
server.listen(0, 'localhost', function () { | |
const addr = server.address(); | |
const req = http.get(`http://${addr.address}:${addr.port}`, function (res) { | |
res.resume(); | |
res.once('end', server.close.bind(server)); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment