Browse Source

net: introduce `Socket#connecting` property

There is no official way to figure out if the socket that you have on
hand is still connecting to the remote host. Introduce
`Socket#connecting`, which is essentially an unprefixed `_connecting`
property that we already had.

PR-URL: https://github.com/nodejs/node/pull/6404
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
process-exit-stdio-flushing
Fedor Indutny 9 years ago
parent
commit
cee4c25c92
  1. 6
      doc/api/net.md
  2. 2
      lib/_tls_legacy.js
  3. 10
      lib/_tls_wrap.js
  4. 35
      lib/net.js
  5. 2
      test/parallel/test-net-connect-buffer.js
  6. 21
      test/parallel/test-net-socket-connecting.js

6
doc/api/net.md

@ -400,6 +400,12 @@ The `connectListener` parameter will be added as a listener for the
As [`socket.connect(options\[, connectListener\])`][`socket.connect(options, connectListener)`], As [`socket.connect(options\[, connectListener\])`][`socket.connect(options, connectListener)`],
with options either as either `{port: port, host: host}` or `{path: path}`. with options either as either `{port: port, host: host}` or `{path: path}`.
### socket.connecting
If `true` - [`socket.connect(options\[, connectListener\])`][] was called and
haven't yet finished. Will be set to `false` before emitting `connect` event
and/or calling [`socket.connect(options\[, connectListener\])`][]'s callback.
### socket.destroy() ### socket.destroy()
Ensures that no more I/O activity happens on this socket. Only necessary in Ensures that no more I/O activity happens on this socket. Only necessary in

2
lib/_tls_legacy.js

@ -477,7 +477,7 @@ CryptoStream.prototype._done = function() {
// readyState is deprecated. Don't use it. // readyState is deprecated. Don't use it.
Object.defineProperty(CryptoStream.prototype, 'readyState', { Object.defineProperty(CryptoStream.prototype, 'readyState', {
get: function() { get: function() {
if (this._connecting) { if (this.connecting) {
return 'opening'; return 'opening';
} else if (this.readable && this.writable) { } else if (this.readable && this.writable) {
return 'open'; return 'open';

10
lib/_tls_wrap.js

@ -272,7 +272,7 @@ function TLSSocket(socket, options) {
this._init(socket, wrap); this._init(socket, wrap);
// Make sure to setup all required properties like: `_connecting` before // Make sure to setup all required properties like: `connecting` before
// starting the flow of the data // starting the flow of the data
this.readable = true; this.readable = true;
this.writable = true; this.writable = true;
@ -466,9 +466,9 @@ TLSSocket.prototype._init = function(socket, wrap) {
this._parent = socket; this._parent = socket;
// To prevent assertion in afterConnect() and properly kick off readStart // To prevent assertion in afterConnect() and properly kick off readStart
this._connecting = socket._connecting || !socket._handle; this.connecting = socket.connecting || !socket._handle;
socket.once('connect', function() { socket.once('connect', function() {
self._connecting = false; self.connecting = false;
self.emit('connect'); self.emit('connect');
}); });
} }
@ -480,7 +480,7 @@ TLSSocket.prototype._init = function(socket, wrap) {
}); });
} else { } else {
assert(!socket); assert(!socket);
this._connecting = true; this.connecting = true;
} }
}; };
@ -581,7 +581,7 @@ TLSSocket.prototype._finishInit = function() {
}; };
TLSSocket.prototype._start = function() { TLSSocket.prototype._start = function() {
if (this._connecting) { if (this.connecting) {
this.once('connect', function() { this.once('connect', function() {
this._start(); this._start();
}); });

35
lib/net.js

@ -119,7 +119,7 @@ const BYTES_READ = Symbol('bytesRead');
function Socket(options) { function Socket(options) {
if (!(this instanceof Socket)) return new Socket(options); if (!(this instanceof Socket)) return new Socket(options);
this._connecting = false; this.connecting = false;
this._hadError = false; this._hadError = false;
this._handle = null; this._handle = null;
this._parent = null; this._parent = null;
@ -202,7 +202,7 @@ Socket.prototype._unrefTimer = function unrefTimer() {
// so that only the writable side will be cleaned up. // so that only the writable side will be cleaned up.
function onSocketFinish() { function onSocketFinish() {
// If still connecting - defer handling 'finish' until 'connect' will happen // If still connecting - defer handling 'finish' until 'connect' will happen
if (this._connecting) { if (this.connecting) {
debug('osF: not yet connected'); debug('osF: not yet connected');
return this.once('connect', onSocketFinish); return this.once('connect', onSocketFinish);
} }
@ -367,9 +367,16 @@ Socket.prototype.address = function() {
}; };
Object.defineProperty(Socket.prototype, '_connecting', {
get: function() {
return this.connecting;
}
});
Object.defineProperty(Socket.prototype, 'readyState', { Object.defineProperty(Socket.prototype, 'readyState', {
get: function() { get: function() {
if (this._connecting) { if (this.connecting) {
return 'opening'; return 'opening';
} else if (this.readable && this.writable) { } else if (this.readable && this.writable) {
return 'open'; return 'open';
@ -397,7 +404,7 @@ Object.defineProperty(Socket.prototype, 'bufferSize', {
Socket.prototype._read = function(n) { Socket.prototype._read = function(n) {
debug('_read'); debug('_read');
if (this._connecting || !this._handle) { if (this.connecting || !this._handle) {
debug('_read wait for connection'); debug('_read wait for connection');
this.once('connect', () => this._read(n)); this.once('connect', () => this._read(n));
} else if (!this._handle.reading) { } else if (!this._handle.reading) {
@ -430,7 +437,7 @@ function maybeDestroy(socket) {
if (!socket.readable && if (!socket.readable &&
!socket.writable && !socket.writable &&
!socket.destroyed && !socket.destroyed &&
!socket._connecting && !socket.connecting &&
!socket._writableState.length) { !socket._writableState.length) {
socket.destroy(); socket.destroy();
} }
@ -465,7 +472,7 @@ Socket.prototype._destroy = function(exception, cb) {
return; return;
} }
this._connecting = false; this.connecting = false;
this.readable = this.writable = false; this.readable = this.writable = false;
@ -648,7 +655,7 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
// If we are still connecting, then buffer this for later. // If we are still connecting, then buffer this for later.
// The Writable logic will buffer up any more writes while // The Writable logic will buffer up any more writes while
// waiting for this one to be done. // waiting for this one to be done.
if (this._connecting) { if (this.connecting) {
this._pendingData = data; this._pendingData = data;
this._pendingEncoding = encoding; this._pendingEncoding = encoding;
this.once('connect', function() { this.once('connect', function() {
@ -803,7 +810,7 @@ function connect(self, address, port, addressType, localAddress, localPort) {
// TODO return promise from Socket.prototype.connect which // TODO return promise from Socket.prototype.connect which
// wraps _connectReq. // wraps _connectReq.
assert.ok(self._connecting); assert.ok(self.connecting);
var err; var err;
@ -913,7 +920,7 @@ Socket.prototype.connect = function(options, cb) {
this._unrefTimer(); this._unrefTimer();
this._connecting = true; this.connecting = true;
this.writable = true; this.writable = true;
if (pipe) { if (pipe) {
@ -952,7 +959,7 @@ function lookupAndConnect(self, options) {
var addressType = exports.isIP(host); var addressType = exports.isIP(host);
if (addressType) { if (addressType) {
process.nextTick(function() { process.nextTick(function() {
if (self._connecting) if (self.connecting)
connect(self, host, port, addressType, localAddress, localPort); connect(self, host, port, addressType, localAddress, localPort);
}); });
return; return;
@ -980,7 +987,7 @@ function lookupAndConnect(self, options) {
// It's possible we were destroyed while looking this up. // It's possible we were destroyed while looking this up.
// XXX it would be great if we could cancel the promise returned by // XXX it would be great if we could cancel the promise returned by
// the look up. // the look up.
if (!self._connecting) return; if (!self.connecting) return;
if (err) { if (err) {
// net.createConnection() creates a net.Socket object and // net.createConnection() creates a net.Socket object and
@ -1048,8 +1055,8 @@ function afterConnect(status, handle, req, readable, writable) {
debug('afterConnect'); debug('afterConnect');
assert.ok(self._connecting); assert.ok(self.connecting);
self._connecting = false; self.connecting = false;
self._sockname = null; self._sockname = null;
if (status == 0) { if (status == 0) {
@ -1065,7 +1072,7 @@ function afterConnect(status, handle, req, readable, writable) {
self.read(0); self.read(0);
} else { } else {
self._connecting = false; self.connecting = false;
var details; var details;
if (req.localAddress && req.localPort) { if (req.localAddress && req.localPort) {
details = req.localAddress + ':' + req.localPort; details = req.localAddress + ':' + req.localPort;

2
test/parallel/test-net-connect-buffer.js

@ -40,7 +40,7 @@ tcp.listen(common.PORT, function() {
connectHappened = true; connectHappened = true;
}); });
console.log('_connecting = ' + socket._connecting); console.log('connecting = ' + socket.connecting);
assert.equal('opening', socket.readyState); assert.equal('opening', socket.readyState);

21
test/parallel/test-net-socket-connecting.js

@ -0,0 +1,21 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const net = require('net');
const server = net.createServer((conn) => {
conn.end();
server.close();
}).listen(common.PORT, () => {
const client = net.connect(common.PORT, () => {
assert.strictEqual(client.connecting, false);
// Legacy getter
assert.strictEqual(client._connecting, false);
client.end();
});
assert.strictEqual(client.connecting, true);
// Legacy getter
assert.strictEqual(client._connecting, true);
});
Loading…
Cancel
Save