From 16b59cbc74c8fe2f8b30f3af4c2f885b7bfb6030 Mon Sep 17 00:00:00 2001 From: Peter Rust Date: Mon, 1 Jul 2013 15:46:49 -0700 Subject: [PATCH] http: use an unref'd timer to fix delay in exit There was previously up to a second exit delay when exiting node right after an http request/response, due to the utcDate() function doing a setTimeout to update the cached date/time. Fixing this should increase the performance of our http tests. --- lib/http.js | 9 +++-- test/simple/test-http-exit-delay.js | 60 +++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 test/simple/test-http-exit-delay.js diff --git a/lib/http.js b/lib/http.js index ab36cd749140a6..2dc1dabb0b97aa 100644 --- a/lib/http.js +++ b/lib/http.js @@ -22,6 +22,7 @@ var util = require('util'); var net = require('net'); var Stream = require('stream'); +var timers = require('timers'); var url = require('url'); var EventEmitter = require('events').EventEmitter; var FreeList = require('freelist').FreeList; @@ -274,12 +275,14 @@ function utcDate() { if (!dateCache) { var d = new Date(); dateCache = d.toUTCString(); - setTimeout(function() { - dateCache = undefined; - }, 1000 - d.getMilliseconds()); + timers.enroll(utcDate, 1000 - d.getMilliseconds()); + timers._unrefActive(utcDate); } return dateCache; } +utcDate._onTimeout = function() { + dateCache = undefined; +}; /* Abstract base class for ServerRequest and ClientResponse. */ diff --git a/test/simple/test-http-exit-delay.js b/test/simple/test-http-exit-delay.js new file mode 100644 index 00000000000000..3643492735a16d --- /dev/null +++ b/test/simple/test-http-exit-delay.js @@ -0,0 +1,60 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var assert = require('assert'); +var common = require('../common.js'); +var http = require('http'); + +var start; +var server = http.createServer(function(req, res) { + req.resume(); + req.on('end', function() { + res.end('Success'); + }); + + server.close(function() { + start = process.hrtime(); + }); +}); + +server.listen(common.PORT, 'localhost', function() { + var interval_id = setInterval(function() { + if (new Date().getMilliseconds() > 100) + return; + + var req = http.request({ + 'host': 'localhost', + 'port': common.PORT, + 'agent': false, + 'method': 'PUT' + }); + + req.end('Test'); + clearInterval(interval_id); + }, 10); +}); + +process.on('exit', function() { + var d = process.hrtime(start); + assert.equal(d[0], 0); + assert(d[1] / 1e9 < 0.03); + console.log('ok'); +});