Skip to content

Commit 7393ea3

Browse files
committed
fix: use fasttimers for all connection timeouts
1 parent 89a46dd commit 7393ea3

File tree

4 files changed

+736
-697
lines changed

4 files changed

+736
-697
lines changed

lib/dispatcher/client-h1.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,9 @@ class Parser {
165165
setTimeout (delay, type) {
166166
this.timeoutType = type
167167
if (delay !== this.timeoutValue) {
168-
this.timeout && timers.clearTimeout(this.timeout)
168+
this.timeout && timers.clearFastTimeout(this.timeout)
169169
if (delay) {
170-
this.timeout = timers.setTimeout(onParserTimeout, delay, new WeakRef(this))
171-
// istanbul ignore else: only for jest
172-
if (this.timeout.unref) {
173-
this.timeout.unref()
174-
}
170+
this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this))
175171
} else {
176172
this.timeout = null
177173
}

lib/util/timers.js

+33-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ module.exports = {
347347
* The clearTimeout method cancels an instantiated Timer previously created
348348
* by calling setTimeout.
349349
*
350-
* @param {FastTimer} timeout
350+
* @param {NodeJS.Timeout|FastTimer} timeout
351351
*/
352352
clearTimeout (timeout) {
353353
// If the timeout is a FastTimer, call its own clear method.
@@ -362,6 +362,31 @@ module.exports = {
362362
nativeClearTimeout(timeout)
363363
}
364364
},
365+
/**
366+
* The setFastTimeout() method sets a fastTimer which executes a function once
367+
* the timer expires.
368+
* @param {Function} callback A function to be executed after the timer
369+
* expires.
370+
* @param {number} delay The time, in milliseconds that the timer should
371+
* wait before the specified function or code is executed.
372+
* @param {*} [arg] An optional argument to be passed to the callback function
373+
* when the timer expires.
374+
* @returns {FastTimer}
375+
*/
376+
setFastTimeout (callback, delay, arg) {
377+
// If the delay is less than or equal to the RESOLUTION_MS value return a
378+
// native Node.js Timer instance.
379+
return new FastTimer(callback, delay, arg)
380+
},
381+
/**
382+
* The clearTimeout method cancels an instantiated FastTimer previously
383+
* created by calling setFastTimeout.
384+
*
385+
* @param {FastTimer} timeout
386+
*/
387+
clearFastTimeout (timeout) {
388+
timeout.clear()
389+
},
365390
/**
366391
* The now method returns the value of the internal fast timer clock.
367392
*
@@ -370,6 +395,13 @@ module.exports = {
370395
now () {
371396
return fastNow
372397
},
398+
/**
399+
* Trigger the onTick function to process the fastTimers array.
400+
* Exported for testing purposes only.
401+
*/
402+
tick () {
403+
onTick()
404+
},
373405
/**
374406
* Exporting for testing purposes only.
375407
* Marking as deprecated to discourage any use outside of testing.

test/issue-3356.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const { tspl } = require('@matteo.collina/tspl')
44
const { test, after } = require('node:test')
55
const { createServer } = require('node:http')
66
const { once } = require('node:events')
7-
7+
const { tick: fastTimerTick } = require('../lib/util/timers')
88
const { fetch, Agent, RetryAgent } = require('..')
99

1010
test('https://github.com/nodejs/undici/issues/3356', async (t) => {
@@ -42,6 +42,10 @@ test('https://github.com/nodejs/undici/issues/3356', async (t) => {
4242
const response = await fetch(`http://localhost:${server.address().port}`, {
4343
dispatcher: agent
4444
})
45+
46+
fastTimerTick()
47+
fastTimerTick()
48+
4549
setTimeout(async () => {
4650
try {
4751
t.equal(response.status, 200)

0 commit comments

Comments
 (0)