Skip to content

Commit 55a2bd2

Browse files
evantorrieMylesBorins
authored andcommitted
http: eliminate capture of ClientRequest in Agent
Keepalive sockets that are returned to the agent's freesocket pool were previously capturing a reference to the ClientRequest that initiated the request. This commit eliminates that by moving the installation of the socket listeners to a different function. Backport-PR-URL: #15500 PR-URL: #10134 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Evan Lucas <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent f364d7c commit 55a2bd2

File tree

1 file changed

+31
-27
lines changed

1 file changed

+31
-27
lines changed

lib/_http_agent.js

+31-27
Original file line numberDiff line numberDiff line change
@@ -206,37 +206,41 @@ Agent.prototype.createSocket = function(req, options, cb) {
206206
}
207207
self.sockets[name].push(s);
208208
debug('sockets', name, self.sockets[name].length);
209-
210-
function onFree() {
211-
self.emit('free', s, options);
212-
}
213-
s.on('free', onFree);
214-
215-
function onClose(err) {
216-
debug('CLIENT socket onClose');
217-
// This is the only place where sockets get removed from the Agent.
218-
// If you want to remove a socket from the pool, just close it.
219-
// All socket errors end in a close event anyway.
220-
self.removeSocket(s, options);
221-
}
222-
s.on('close', onClose);
223-
224-
function onRemove() {
225-
// We need this function for cases like HTTP 'upgrade'
226-
// (defined by WebSockets) where we need to remove a socket from the
227-
// pool because it'll be locked up indefinitely
228-
debug('CLIENT socket onRemove');
229-
self.removeSocket(s, options);
230-
s.removeListener('close', onClose);
231-
s.removeListener('free', onFree);
232-
s.removeListener('agentRemove', onRemove);
233-
}
234-
s.on('agentRemove', onRemove);
209+
installListeners(self, s, options);
235210
cb(null, s);
236211
}
237212
};
238213

239-
Agent.prototype.removeSocket = function(s, options) {
214+
function installListeners(agent, s, options) {
215+
function onFree() {
216+
debug('CLIENT socket onFree');
217+
agent.emit('free', s, options);
218+
}
219+
s.on('free', onFree);
220+
221+
function onClose(err) {
222+
debug('CLIENT socket onClose');
223+
// This is the only place where sockets get removed from the Agent.
224+
// If you want to remove a socket from the pool, just close it.
225+
// All socket errors end in a close event anyway.
226+
agent.removeSocket(s, options);
227+
}
228+
s.on('close', onClose);
229+
230+
function onRemove() {
231+
// We need this function for cases like HTTP 'upgrade'
232+
// (defined by WebSockets) where we need to remove a socket from the
233+
// pool because it'll be locked up indefinitely
234+
debug('CLIENT socket onRemove');
235+
agent.removeSocket(s, options);
236+
s.removeListener('close', onClose);
237+
s.removeListener('free', onFree);
238+
s.removeListener('agentRemove', onRemove);
239+
}
240+
s.on('agentRemove', onRemove);
241+
}
242+
243+
Agent.prototype.removeSocket = function removeSocket(s, options) {
240244
var name = this.getName(options);
241245
debug('removeSocket', name, 'writable:', s.writable);
242246
var sets = [this.sockets];

0 commit comments

Comments
 (0)