You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Race condition between socket timeout and new client requests #23
Environment = Node 0.10.38
I've been debugging a nasty ECONNRESET error occuring when the keepAliveTimeout is very close to the interval between two http requests.
Setting the NODE_DEBUG variable to "http,agentkeepalive", I could see the following interactions:
[Error: socket hang up] code: 'ECONNRESET'
Error: socket hang up
at createHangUpError (http.js:1473:15)
at Socket.socketCloseListener (http.js:1523:23)
at Socket.emit (events.js:117:20)
at TCP.close (net.js:466:12)
What's wrong with this sequence of events is that the onTimeout method is called but a new http request is added very shortly after. In the meantime, the net.Socket.destroy() call effectively destroys the socket in the middle of the request.
I will prepare a pull request for a change to onTimeout() that removes the socket from self.freeSockets immediately instead of waiting for the 'close' event. This way no new request will be channeled through this socket during its destruction.
Unfortunately, I'm not able to provide a simple test case because I don't know how to artificially expand the delay between the 'timeout' and 'close' events.
I was able to reproduce the problem with this small script:
varAgent=require('agentkeepalive');varhttp=require('http');var_keepaliveAgent=newAgent({maxSockets: 1,maxFreeSockets: 1,keepAliveTimeout: 1000});varoptions={hostname: 'www.google.com',port: 80,path: '/',method: 'GET',agent : _keepaliveAgent};vargetRequest=function(){varreq=http.request(options,function(res){res.on('data',function(chunk){console.log('BODY: '+chunk);});res.on('end',function(){console.log('END REQ');});});req.on('error',function(e){console.log('problem with request: ',e);});returnreq;};varreq=getRequest();// Get a reference to the socket.req.on('socket',function(sock){// Listen to timeout and send another request immediately.sock.on('timeout',function(){getRequest().end();});});req.end();setTimeout(function(){// Just keep the process hanging because listening to 'timeout' is not enough to keep the process spinning.},2500);
The first http request succeeds, the second fails with ECONNRESET.
Activity
pmalouin commentedon Apr 23, 2015
I was able to reproduce the problem with this small script:
The first http request succeeds, the second fails with ECONNRESET.
fengmk2 commentedon Apr 25, 2015
e6a83a5
pmalouin commentedon Apr 27, 2015
Thanks, I updated and it's all good for me!