Browse Source

net: persist net.Socket options before connect

Remembers net.Socket options called before connect and retroactively
applies them after the handle has been created.

This change makes the following function calls more user-friendly:

- setKeepAlive()
- setNoDelay()
- ref()
- unref()

Related: https://github.com/joyent/node/issues/7077 and
https://github.com/joyent/node/issues/8572

Fixes: https://github.com/joyent/node/issues/7077
Fixes: https://github.com/joyent/node/issues/8572
PR-URL: https://github.com/nodejs/io.js/pull/1518
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Roman Reiss <me@silverwind.io>
v2.3.1-release
Evan Lucas 10 years ago
parent
commit
85d9983009
  1. 31
      lib/net.js
  2. 33
      test/parallel/test-net-persistent-keepalive.js
  3. 33
      test/parallel/test-net-persistent-nodelay.js
  4. 39
      test/parallel/test-net-persistent-ref-unref.js

31
lib/net.js

@ -321,14 +321,25 @@ Socket.prototype._onTimeout = function() {
Socket.prototype.setNoDelay = function(enable) {
if (!this._handle) {
this.once('connect',
enable ? this.setNoDelay : this.setNoDelay.bind(this, enable));
return;
}
// backwards compatibility: assume true when `enable` is omitted
if (this._handle && this._handle.setNoDelay)
if (this._handle.setNoDelay)
this._handle.setNoDelay(enable === undefined ? true : !!enable);
};
Socket.prototype.setKeepAlive = function(setting, msecs) {
if (this._handle && this._handle.setKeepAlive)
if (!this._handle) {
this.once('connect', this.setKeepAlive.bind(this, setting, msecs));
return;
}
if (this._handle.setKeepAlive)
this._handle.setKeepAlive(setting, ~~(msecs / 1000));
};
@ -971,14 +982,22 @@ function connectErrorNT(self, err, options) {
Socket.prototype.ref = function() {
if (this._handle)
this._handle.ref();
if (!this._handle) {
this.once('connect', this.ref);
return;
}
this._handle.ref();
};
Socket.prototype.unref = function() {
if (this._handle)
this._handle.unref();
if (!this._handle) {
this.once('connect', this.unref);
return;
}
this._handle.unref();
};

33
test/parallel/test-net-persistent-keepalive.js

@ -0,0 +1,33 @@
'use strict';
var common = require('../common');
var assert = require('assert');
var net = require('net');
var serverConnection;
var echoServer = net.createServer(function(connection) {
serverConnection = connection;
connection.setTimeout(0);
assert.equal(typeof connection.setKeepAlive, 'function');
connection.on('end', function() {
connection.end();
});
});
echoServer.listen(common.PORT);
echoServer.on('listening', function() {
var clientConnection = new net.Socket();
// send a keepalive packet after 1000 ms
// and make sure it persists
clientConnection.setKeepAlive(true, 400);
clientConnection.connect(common.PORT);
clientConnection.setTimeout(0);
setTimeout(function() {
// make sure both connections are still open
assert.equal(serverConnection.readyState, 'open');
assert.equal(clientConnection.readyState, 'open');
serverConnection.end();
clientConnection.end();
echoServer.close();
}, 600);
});

33
test/parallel/test-net-persistent-nodelay.js

@ -0,0 +1,33 @@
'use strict';
var common = require('../common');
var assert = require('assert');
var net = require('net');
var TCPWrap = process.binding('tcp_wrap').TCP;
var echoServer = net.createServer(function(connection) {
connection.end();
});
echoServer.listen(common.PORT);
var callCount = 0;
var Socket = net.Socket;
var setNoDelay = TCPWrap.prototype.setNoDelay;
TCPWrap.prototype.setNoDelay = function(enable) {
setNoDelay.call(this, enable);
callCount++;
};
echoServer.on('listening', function() {
var sock1 = new Socket();
// setNoDelay before the handle is created
// there is probably a better way to test this
sock1.setNoDelay();
sock1.connect(common.PORT);
sock1.on('end', function() {
assert.equal(callCount, 1);
echoServer.close();
});
});

39
test/parallel/test-net-persistent-ref-unref.js

@ -0,0 +1,39 @@
'use strict';
var common = require('../common');
var assert = require('assert');
var net = require('net');
var TCPWrap = process.binding('tcp_wrap').TCP;
var echoServer = net.createServer(function(conn) {
conn.end();
});
var ref = TCPWrap.prototype.ref;
var unref = TCPWrap.prototype.unref;
var refCount = 0;
TCPWrap.prototype.ref = function() {
ref.call(this);
refCount++;
assert.equal(refCount, 0);
};
TCPWrap.prototype.unref = function() {
unref.call(this);
refCount--;
assert.equal(refCount, -1);
};
echoServer.listen(common.PORT);
echoServer.on('listening', function() {
var sock = new net.Socket();
sock.unref();
sock.ref();
sock.connect(common.PORT);
sock.on('end', function() {
assert.equal(refCount, 0);
echoServer.close();
});
});
Loading…
Cancel
Save