http: use an unref'd timer to fix delay in exit
authorPeter Rust <peter@cornerstonenw.com>
Mon, 1 Jul 2013 22:46:49 +0000 (15:46 -0700)
committerTimothy J Fontaine <tjfontaine@gmail.com>
Mon, 1 Jul 2013 23:02:25 +0000 (16:02 -0700)
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
test/simple/test-http-exit-delay.js [new file with mode: 0644]

index ab36cd7..2dc1dab 100644 (file)
@@ -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 (file)
index 0000000..3643492
--- /dev/null
@@ -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');
+});