net: Timeouts should work before DNS resolution

This commit is contained in:
Ryan Dahl 2011-01-12 12:59:58 -08:00
parent 33c33949b2
commit 5f795efd4e
2 changed files with 59 additions and 19 deletions

View File

@ -1,6 +1,7 @@
var util = require('util'); var util = require('util');
var events = require('events'); var events = require('events');
var stream = require('stream'); var stream = require('stream');
var timers = require('timers');;
var kMinPoolSpace = 128; var kMinPoolSpace = 128;
var kPoolSize = 40 * 1024; var kPoolSize = 40 * 1024;
@ -420,7 +421,7 @@ Socket.prototype._writeOut = function(data, encoding, fd, cb) {
debug('wrote ' + bytesWritten + ' to socket. [fd, off, len] = ' + debug('wrote ' + bytesWritten + ' to socket. [fd, off, len] = ' +
JSON.stringify([this.fd, off, len]) + '\n'); JSON.stringify([this.fd, off, len]) + '\n');
require('timers').active(this); timers.active(this);
if (bytesWritten == len) { if (bytesWritten == len) {
// awesome. sent to buffer. // awesome. sent to buffer.
@ -498,6 +499,8 @@ Socket.prototype.setEncoding = function(encoding) {
function doConnect(socket, port, host) { function doConnect(socket, port, host) {
timers.active(socket);
try { try {
connect(socket.fd, port, host); connect(socket.fd, port, host);
} catch (e) { } catch (e) {
@ -601,7 +604,7 @@ Socket.prototype._onReadable = function() {
if (self.onend) self.onend(); if (self.onend) self.onend();
} else if (bytesRead > 0) { } else if (bytesRead > 0) {
require('timers').active(self); timers.active(self);
var start = pool.used; var start = pool.used;
var end = pool.used + bytesRead; var end = pool.used + bytesRead;
@ -635,7 +638,7 @@ Socket.prototype.connect = function() {
if (self.fd) throw new Error('Socket already opened'); if (self.fd) throw new Error('Socket already opened');
if (!self._readWatcher) throw new Error('No readWatcher'); if (!self._readWatcher) throw new Error('No readWatcher');
require('timers').active(socket); timers.active(this);
self._connecting = true; // set false in doConnect self._connecting = true; // set false in doConnect
self.writable = true; self.writable = true;
@ -659,6 +662,7 @@ Socket.prototype.connect = function() {
if (err) { if (err) {
self.emit('error', err); self.emit('error', err);
} else { } else {
timers.active(self);
self.type = addressType == 4 ? 'tcp4' : 'tcp6'; self.type = addressType == 4 ? 'tcp4' : 'tcp6';
self.fd = socket(self.type); self.fd = socket(self.type);
doConnect(self, port, ip); doConnect(self, port, ip);
@ -688,10 +692,10 @@ Socket.prototype.setKeepAlive = function(enable, time) {
Socket.prototype.setTimeout = function(msecs) { Socket.prototype.setTimeout = function(msecs) {
if (msecs > 0) { if (msecs > 0) {
require('timers').enroll(this, msecs); timers.enroll(this, msecs);
if (this.fd) { require('timers').active(this); } if (this.fd) { timers.active(this); }
} else if (msecs === 0) { } else if (msecs === 0) {
require('timers').unenroll(this); timers.unenroll(this);
} }
}; };
@ -742,7 +746,7 @@ Socket.prototype.destroy = function(exception) {
this._readWatcher = null; this._readWatcher = null;
} }
require('timers').unenroll(this); timers.unenroll(this);
if (this.server) { if (this.server) {
this.server.connections--; this.server.connections--;

View File

@ -1,37 +1,73 @@
// This example attempts to time out before the connection is established // This example attempts to time out before the connection is established
// https://groups.google.com/forum/#!topic/nodejs/UE0ZbfLt6t8 // https://groups.google.com/forum/#!topic/nodejs/UE0ZbfLt6t8
// https://groups.google.com/forum/#!topic/nodejs-dev/jR7-5UDqXkw // https://groups.google.com/forum/#!topic/nodejs-dev/jR7-5UDqXkw
//
// TODO: how to do this without relying on the responses of specific sites?
var common = require('../common'); var common = require('../common');
var net = require('net'); var net = require('net');
var assert = require('assert'); var assert = require('assert');
var start = new Date(); var start = new Date();
var gotTimeout = false;
var gotConnect = false; var gotTimeout0 = false;
var gotTimeout1 = false;
var gotConnect0 = false;
var gotConnect1 = false;
var T = 100; var T = 100;
var socket = net.createConnection(9999, '23.23.23.23');
socket.setTimeout(T); // With DNS
var socket0 = net.createConnection(9999, 'google.com');
socket.on('timeout', function() { socket0.setTimeout(T);
socket0.on('timeout', function() {
console.error("timeout"); console.error("timeout");
gotTimeout = true; gotTimeout0 = true;
var now = new Date(); var now = new Date();
assert.ok(now - start < T + 500); assert.ok(now - start < T + 500);
socket.end(); socket0.end();
}); });
socket.on('connect', function() { socket0.on('connect', function() {
console.error("connect"); console.error("connect");
gotConnect = true; gotConnect0 = true;
socket.end(); socket0.end();
}); });
// Without DNS
var socket1 = net.createConnection(9999, '24.24.24.24');
socket1.setTimeout(T);
socket1.on('timeout', function() {
console.error("timeout");
gotTimeout1 = true;
var now = new Date();
assert.ok(now - start < T + 500);
socket1.end();
});
socket1.on('connect', function() {
console.error("connect");
gotConnect1 = true;
socket1.end();
});
process.on('exit', function() { process.on('exit', function() {
assert.ok(gotTimeout); assert.ok(gotTimeout0);
assert.ok(!gotConnect); assert.ok(!gotConnect0);
assert.ok(gotTimeout1);
assert.ok(!gotConnect1);
}); });