Skip to content

Commit 175cf08

Browse files
committed
WIP net: enable emitclose in socket
1 parent fef2128 commit 175cf08

File tree

6 files changed

+33
-22
lines changed

6 files changed

+33
-22
lines changed

lib/internal/streams/destroy.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,15 @@ function _destroy(self, err, cb) {
151151

152152
function emitErrorCloseNT(self, err) {
153153
emitErrorNT(self, err);
154-
emitCloseNT(self);
154+
emitCloseNT(self, err);
155155
}
156156

157-
function emitCloseNT(self) {
157+
function emitCloseNT(self, err) {
158158
const r = self._readableState;
159159
const w = self._writableState;
160+
const emitClose = (w && w.emitClose) || (r && r.emitClose);
161+
const shouldPassErrorFlag = (w && w.errorFlagOnClose) ||
162+
(r && r.errorFlagOnClose);
160163

161164
if (w) {
162165
w.closeEmitted = true;
@@ -165,8 +168,12 @@ function emitCloseNT(self) {
165168
r.closeEmitted = true;
166169
}
167170

168-
if ((w && w.emitClose) || (r && r.emitClose)) {
169-
self.emit('close');
171+
if (emitClose) {
172+
if (shouldPassErrorFlag) {
173+
self.emit('close', Boolean(err));
174+
} else {
175+
self.emit('close')
176+
}
170177
}
171178
}
172179

lib/internal/streams/readable.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ function ReadableState(options, stream, isDuplex) {
134134
// Should close be emitted on destroy. Defaults to true.
135135
this.emitClose = !options || options.emitClose !== false;
136136

137+
// Should a boolean flag be passed as argument when emitting close if an error
138+
// occurred
139+
this.errorFlagOnClose = options && options.errorFlagOnClose === true;
140+
137141
// Should .destroy() be called after 'end' (and potentially 'finish').
138142
this.autoDestroy = !options || options.autoDestroy !== false;
139143

lib/internal/streams/writable.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ function WritableState(options, stream, isDuplex) {
180180
// Should close be emitted on destroy. Defaults to true.
181181
this.emitClose = !options || options.emitClose !== false;
182182

183+
// Should a boolean flag be passed as argument when emitting close if an error
184+
// occurred
185+
this.errorFlagOnClose = options && options.errorFlagOnClose === true;
186+
183187
// Should .destroy() be called after 'finish' (and potentially 'end').
184188
this.autoDestroy = !options || options.autoDestroy !== false;
185189

lib/net.js

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,9 @@ function Socket(options) {
301301

302302
// Default to *not* allowing half open sockets.
303303
options.allowHalfOpen = Boolean(options.allowHalfOpen);
304-
// For backwards compat do not emit close on destroy.
305-
options.emitClose = false;
304+
// For backward compatibility, pass a flag when emitting close for
305+
// comunicating that an error occurred.
306+
options.errorFlagOnClose = true;
306307
options.autoDestroy = true;
307308
// Handle strings directly.
308309
options.decodeStrings = false;
@@ -657,28 +658,20 @@ Socket.prototype._destroy = function(exception, cb) {
657658
if (this._handle) {
658659
if (this !== process.stderr)
659660
debug('close handle');
660-
const isException = exception ? true : false;
661+
661662
// `bytesRead` and `kBytesWritten` should be accessible after `.destroy()`
662663
this[kBytesRead] = this._handle.bytesRead;
663664
this[kBytesWritten] = this._handle.bytesWritten;
664665

665666
this._handle.close(() => {
666667
debug('emit close');
667-
if (this._writableState) {
668-
this._writableState.closed = true;
669-
}
670-
if (this._readableState) {
671-
this._readableState.closed = true;
672-
}
673-
this.emit('close', isException);
668+
cb(exception);
674669
});
675670
this._handle.onread = noop;
676671
this._handle = null;
677672
this._sockname = null;
678-
cb(exception);
679673
} else {
680674
cb(exception);
681-
process.nextTick(emitCloseNT, this);
682675
}
683676

684677
if (this._server) {
@@ -1657,12 +1650,6 @@ Server.prototype._emitCloseIfDrained = function() {
16571650

16581651
function emitCloseNT(self) {
16591652
debug('SERVER: emit close');
1660-
if (self._writableState) {
1661-
self._writableState.closed = true;
1662-
}
1663-
if (self._readableState) {
1664-
self._readableState.closed = true;
1665-
}
16661653
self.emit('close');
16671654
}
16681655

test/parallel/test-http2-respond-with-file-connection-abort.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ server.listen(0, common.mustCall(() => {
2525

2626
req.on('response', common.mustCall(() => {}));
2727
req.once('data', common.mustCall(() => {
28+
// TODO: is this test needed?
29+
// It errors with ERR_HTTP2_NO_SOCKET_MANIPULATION because we are
30+
// calling destroy on the Proxy(ed) socket of the Http2ClientSession
31+
// which causes `emit` to becalled and the error to be thrown.
2832
net.Socket.prototype.destroy.call(client.socket);
2933
server.close();
3034
}));

test/parallel/test-tls-socket-close.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
'use strict';
2+
23
const common = require('../common');
34
if (!common.hasCrypto)
45
common.skip('missing crypto');
@@ -8,6 +9,10 @@ const tls = require('tls');
89
const net = require('net');
910
const fixtures = require('../common/fixtures');
1011

12+
// TODO: is this test needed?
13+
// It fails with a timeout error because the `error` event is never emitted.
14+
// `write` doesn't error, is that a good thing?
15+
1116
// Regression test for https://github.com/nodejs/node/issues/8074
1217
//
1318
// This test has a dependency on the order in which the TCP connection is made,

0 commit comments

Comments
 (0)