@@ -85,6 +85,16 @@ class Agent extends OriginalAgent {
85
85
// including free socket timeout counter
86
86
this . timeoutSocketCount = 0 ;
87
87
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
+ } ) ;
88
98
}
89
99
90
100
get freeSocketKeepAliveTimeout ( ) {
@@ -102,29 +112,24 @@ class Agent extends OriginalAgent {
102
112
return this . options . socketActiveTTL ;
103
113
}
104
114
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 ) {
110
123
let freeSocketTimeout = this . options . freeSocketTimeout ;
111
124
const socketActiveTTL = this . options . socketActiveTTL ;
112
125
if ( socketActiveTTL ) {
113
126
// check socketActiveTTL
114
127
const aliveTime = Date . now ( ) - socket [ SOCKET_CREATED_TIME ] ;
115
128
const diff = socketActiveTTL - aliveTime ;
116
- // destroy it
117
129
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 ;
122
131
}
123
-
124
132
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 ) ;
128
133
freeSocketTimeout = diff ;
129
134
}
130
135
}
@@ -134,12 +139,26 @@ class Agent extends OriginalAgent {
134
139
// try to use socket custom freeSocketTimeout first, support headers['keep-alive']
135
140
// https://github.com/node-modules/urllib/blob/b76053020923f4d99a1c93cf2e16e0c5ba10bacf/lib/urllib.js#L498
136
141
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 ) ;
143
162
}
144
163
return true ;
145
164
}
@@ -362,7 +381,6 @@ function installListeners(agent, socket, options) {
362
381
// pool because it'll be locked up indefinitely
363
382
socket . removeListener ( 'close' , onClose ) ;
364
383
socket . removeListener ( 'error' , onError ) ;
365
- socket . removeListener ( 'free' , onFree ) ;
366
384
socket . removeListener ( 'timeout' , onTimeout ) ;
367
385
socket . removeListener ( 'agentRemove' , onRemove ) ;
368
386
}
0 commit comments