@@ -85,6 +85,16 @@ class Agent extends OriginalAgent {
8585 // including free socket timeout counter
8686 this . timeoutSocketCount = 0 ;
8787 this . timeoutSocketCountLastCheck = 0 ;
88+
89+ this . on ( 'free' , socket => {
90+ // https://github.com/nodejs/node/pull/32000
91+ // Node.js native agent will check socket timeout eqs agent.options.timeout.
92+ // Use the ttl or freeSocketTimeout to overwrite.
93+ const timeout = this . calcSocketTimeout ( socket ) ;
94+ if ( timeout > 0 && socket . timeout !== timeout ) {
95+ socket . setTimeout ( timeout ) ;
96+ }
97+ } ) ;
8898 }
8999
90100 get freeSocketKeepAliveTimeout ( ) {
@@ -102,29 +112,24 @@ class Agent extends OriginalAgent {
102112 return this . options . socketActiveTTL ;
103113 }
104114
105- keepSocketAlive ( socket ) {
106- const result = super . keepSocketAlive ( socket ) ;
107- // should not keepAlive, do nothing
108- if ( ! result ) return result ;
109-
115+ /**
116+ * return < 0: should free socket
117+ * return >= 0: should update socket timeout
118+ * return undefined: not find custom timeout
119+ * @param socket
120+ * @return {number|undefined }
121+ */
122+ calcSocketTimeout ( socket ) {
110123 let freeSocketTimeout = this . options . freeSocketTimeout ;
111124 const socketActiveTTL = this . options . socketActiveTTL ;
112125 if ( socketActiveTTL ) {
113126 // check socketActiveTTL
114127 const aliveTime = Date . now ( ) - socket [ SOCKET_CREATED_TIME ] ;
115128 const diff = socketActiveTTL - aliveTime ;
116- // destroy it
117129 if ( diff <= 0 ) {
118- debug ( '%s(requests: %s, finished: %s) free but need to destroy by TTL, alive %sms(max %sms)' ,
119- socket [ SOCKET_NAME ] , socket [ SOCKET_REQUEST_COUNT ] , socket [ SOCKET_REQUEST_FINISHED_COUNT ] ,
120- aliveTime , socketActiveTTL ) ;
121- return false ;
130+ return diff ;
122131 }
123-
124132 if ( freeSocketTimeout && diff < freeSocketTimeout ) {
125- debug ( '%s(requests: %s, finished: %s) free and wait for %sms TTL timeout' ,
126- socket [ SOCKET_NAME ] , socket [ SOCKET_REQUEST_COUNT ] , socket [ SOCKET_REQUEST_FINISHED_COUNT ] ,
127- diff ) ;
128133 freeSocketTimeout = diff ;
129134 }
130135 }
@@ -134,12 +139,26 @@ class Agent extends OriginalAgent {
134139 // try to use socket custom freeSocketTimeout first, support headers['keep-alive']
135140 // https://github.com/node-modules/urllib/blob/b76053020923f4d99a1c93cf2e16e0c5ba10bacf/lib/urllib.js#L498
136141 const customFreeSocketTimeout = socket . freeSocketTimeout || socket . freeSocketKeepAliveTimeout ;
137- if ( customFreeSocketTimeout && customFreeSocketTimeout < freeSocketTimeout ) {
138- freeSocketTimeout = customFreeSocketTimeout ;
139- }
140- // FIXME: need to make setRequestSocket as a method on Agent class
141- // then we can reset the agent.options.timeout when free socket is reused.
142- socket . setTimeout ( freeSocketTimeout ) ;
142+ return customFreeSocketTimeout || freeSocketTimeout ;
143+ }
144+ }
145+
146+ keepSocketAlive ( socket ) {
147+ const result = super . keepSocketAlive ( socket ) ;
148+ // should not keepAlive, do nothing
149+ if ( ! result ) return result ;
150+
151+ const customTimeout = this . calcSocketTimeout ( socket ) ;
152+ if ( typeof customTimeout === 'undefined' ) {
153+ return true ;
154+ }
155+ if ( customTimeout <= 0 ) {
156+ debug ( '%s(requests: %s, finished: %s) free but need to destroy by TTL, request count %s, diff is %s' ,
157+ socket [ SOCKET_NAME ] , socket [ SOCKET_REQUEST_COUNT ] , socket [ SOCKET_REQUEST_FINISHED_COUNT ] , customTimeout ) ;
158+ return false ;
159+ }
160+ if ( socket . timeout !== customTimeout ) {
161+ socket . setTimeout ( customTimeout ) ;
143162 }
144163 return true ;
145164 }
@@ -362,7 +381,6 @@ function installListeners(agent, socket, options) {
362381 // pool because it'll be locked up indefinitely
363382 socket . removeListener ( 'close' , onClose ) ;
364383 socket . removeListener ( 'error' , onError ) ;
365- socket . removeListener ( 'free' , onFree ) ;
366384 socket . removeListener ( 'timeout' , onTimeout ) ;
367385 socket . removeListener ( 'agentRemove' , onRemove ) ;
368386 }
0 commit comments