Skip to content

Commit 85d9983

Browse files
committed
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: nodejs/node-v0.x-archive#7077 and nodejs/node-v0.x-archive#8572 Fixes: nodejs/node-v0.x-archive#7077 Fixes: nodejs/node-v0.x-archive#8572 PR-URL: #1518 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Roman Reiss <[email protected]>
1 parent 3c44100 commit 85d9983

4 files changed

+130
-6
lines changed

lib/net.js

+25-6
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,25 @@ Socket.prototype._onTimeout = function() {
321321

322322

323323
Socket.prototype.setNoDelay = function(enable) {
324+
if (!this._handle) {
325+
this.once('connect',
326+
enable ? this.setNoDelay : this.setNoDelay.bind(this, enable));
327+
return;
328+
}
329+
324330
// backwards compatibility: assume true when `enable` is omitted
325-
if (this._handle && this._handle.setNoDelay)
331+
if (this._handle.setNoDelay)
326332
this._handle.setNoDelay(enable === undefined ? true : !!enable);
327333
};
328334

329335

330336
Socket.prototype.setKeepAlive = function(setting, msecs) {
331-
if (this._handle && this._handle.setKeepAlive)
337+
if (!this._handle) {
338+
this.once('connect', this.setKeepAlive.bind(this, setting, msecs));
339+
return;
340+
}
341+
342+
if (this._handle.setKeepAlive)
332343
this._handle.setKeepAlive(setting, ~~(msecs / 1000));
333344
};
334345

@@ -971,14 +982,22 @@ function connectErrorNT(self, err, options) {
971982

972983

973984
Socket.prototype.ref = function() {
974-
if (this._handle)
975-
this._handle.ref();
985+
if (!this._handle) {
986+
this.once('connect', this.ref);
987+
return;
988+
}
989+
990+
this._handle.ref();
976991
};
977992

978993

979994
Socket.prototype.unref = function() {
980-
if (this._handle)
981-
this._handle.unref();
995+
if (!this._handle) {
996+
this.once('connect', this.unref);
997+
return;
998+
}
999+
1000+
this._handle.unref();
9821001
};
9831002

9841003

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
var common = require('../common');
3+
var assert = require('assert');
4+
var net = require('net');
5+
6+
var serverConnection;
7+
var echoServer = net.createServer(function(connection) {
8+
serverConnection = connection;
9+
connection.setTimeout(0);
10+
assert.equal(typeof connection.setKeepAlive, 'function');
11+
connection.on('end', function() {
12+
connection.end();
13+
});
14+
});
15+
echoServer.listen(common.PORT);
16+
17+
echoServer.on('listening', function() {
18+
var clientConnection = new net.Socket();
19+
// send a keepalive packet after 1000 ms
20+
// and make sure it persists
21+
clientConnection.setKeepAlive(true, 400);
22+
clientConnection.connect(common.PORT);
23+
clientConnection.setTimeout(0);
24+
25+
setTimeout(function() {
26+
// make sure both connections are still open
27+
assert.equal(serverConnection.readyState, 'open');
28+
assert.equal(clientConnection.readyState, 'open');
29+
serverConnection.end();
30+
clientConnection.end();
31+
echoServer.close();
32+
}, 600);
33+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
var common = require('../common');
3+
var assert = require('assert');
4+
var net = require('net');
5+
var TCPWrap = process.binding('tcp_wrap').TCP;
6+
7+
var echoServer = net.createServer(function(connection) {
8+
connection.end();
9+
});
10+
echoServer.listen(common.PORT);
11+
12+
var callCount = 0;
13+
14+
var Socket = net.Socket;
15+
var setNoDelay = TCPWrap.prototype.setNoDelay;
16+
17+
TCPWrap.prototype.setNoDelay = function(enable) {
18+
setNoDelay.call(this, enable);
19+
callCount++;
20+
};
21+
22+
echoServer.on('listening', function() {
23+
var sock1 = new Socket();
24+
// setNoDelay before the handle is created
25+
// there is probably a better way to test this
26+
27+
sock1.setNoDelay();
28+
sock1.connect(common.PORT);
29+
sock1.on('end', function() {
30+
assert.equal(callCount, 1);
31+
echoServer.close();
32+
});
33+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
var common = require('../common');
3+
var assert = require('assert');
4+
var net = require('net');
5+
var TCPWrap = process.binding('tcp_wrap').TCP;
6+
7+
var echoServer = net.createServer(function(conn) {
8+
conn.end();
9+
});
10+
11+
var ref = TCPWrap.prototype.ref;
12+
var unref = TCPWrap.prototype.unref;
13+
14+
var refCount = 0;
15+
16+
TCPWrap.prototype.ref = function() {
17+
ref.call(this);
18+
refCount++;
19+
assert.equal(refCount, 0);
20+
};
21+
22+
TCPWrap.prototype.unref = function() {
23+
unref.call(this);
24+
refCount--;
25+
assert.equal(refCount, -1);
26+
};
27+
28+
echoServer.listen(common.PORT);
29+
30+
echoServer.on('listening', function() {
31+
var sock = new net.Socket();
32+
sock.unref();
33+
sock.ref();
34+
sock.connect(common.PORT);
35+
sock.on('end', function() {
36+
assert.equal(refCount, 0);
37+
echoServer.close();
38+
});
39+
});

0 commit comments

Comments
 (0)