Skip to content

Commit

Permalink
ensure that fast timers and native timers are set properly
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak committed Sep 5, 2024
1 parent cccd363 commit 51bdb0e
Showing 1 changed file with 28 additions and 18 deletions.
46 changes: 28 additions & 18 deletions lib/dispatcher/client-h1.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,17 @@ let currentBufferRef = null
let currentBufferSize = 0
let currentBufferPtr = null

const TIMEOUT_HEADERS = 1
const TIMEOUT_BODY = 2
const TIMEOUT_KEEP_ALIVE = 3
const USE_NATIVE_TIMER = 0
const USE_FAST_TIMER = 1

// Use fast timers for headers and body to take eventual event loop
// latency into account.
const TIMEOUT_HEADERS = 2 | USE_FAST_TIMER
const TIMEOUT_BODY = 4 | USE_FAST_TIMER

// Use native timers to ignore event loop latency for keep-alive
// handling.
const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER

class Parser {
constructor (client, socket, { exports }) {
Expand Down Expand Up @@ -163,36 +171,38 @@ class Parser {
}

setTimeout (delay, type) {
this.timeoutType = type
if (delay !== this.timeoutValue) {
// If the existing timer and the new timer are of using different timer
// (fast or native) or have different delay, we need to clear the existing
// timer and set a new one.
if (
(type & USE_FAST_TIMER) !== (this.timeoutType & USE_FAST_TIMER) ||
delay !== this.timeoutValue
) {
// If a timeout is already set, clear it with clearTimeout of the fast
// timer implementation, as it can clear fast and native timers.
if (this.timeout) {
timers.clearTimeout(this.timeout)
this.timeout = null
}

if (delay) {
switch (type) {
case TIMEOUT_HEADERS:
case TIMEOUT_BODY:
// Use fast timers for headers and body to take eventual event loop
// latency into account.
this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this))
break
case TIMEOUT_KEEP_ALIVE:
// Use native timers to ignore event loop latency for keep-alive
// handling.
this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this))
this.timeout.unref()
break
if (type & USE_FAST_TIMER) {
this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this))
} else {
this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this))
this.timeout.unref()
}
}

this.timeoutValue = delay
} else if (this.timeout) {
// istanbul ignore else: only for jest
if (this.timeout.refresh) {
this.timeout.refresh()
}
}

this.timeoutType = type
}

resume () {
Expand Down

0 comments on commit 51bdb0e

Please sign in to comment.