httpx/sig/timers.rbs
HoneyryderChuck 8bd4dc1fbd fix timers overhead causing spurious wakeups on the select loop
the change to read/write cancellation-driven timeouts as the default
timeout strategy revealed a performance regression; because these were
built on Timers, which never got unsubscribed, this meant that they were
kept beyond the duration of the request they were created for, and
needlessly got picked up for the next timeout tick.

This was fixed by adding a callback on timer intervals, which
unsubscribes them from the timer group when called; these would then be
activated after the timeout is not needed anymore (request send /
response received), thereby removing the overhead on subsequent
requests.

An additional intervals array is also kept in the connection itself;
timeouts from timers are signalled via socket wait calls, however they
were always resulting in timeouts, even when they shouldn't (ex: expect
timeout and send full response payload as a result), and with the wrong
exception class in some cases. By keeping intervals from its requests
around, and monitoring whether there are relevant request triggers, the
connection can therefore handle a timeout or bail out (so that timers
can fire the correct callback).
2023-10-24 22:53:22 +01:00

45 lines
869 B
Plaintext

module HTTPX
class Timers
@intervals: Array[Interval]
@next_interval_at: Float
def after: (Numeric interval_in_secs, ^() -> void) -> Interval
| (Numeric interval_in_secs) { () -> void } -> Interval
def wait_interval: () -> Numeric?
def fire: (?TimeoutError error) -> void
def initialize: () -> void
class Interval
include Comparable
type callback = ^() -> void
attr_reader interval: Numeric
@callbacks: Array[callback]
@on_empty: callback?
def on_empty: () { () -> void } -> void
def to_f: () -> Float
def <<: (callback) -> void
def delete: (callback) -> void
def elapse: (Numeric elapsed) -> Numeric
def elapsed?: () -> bool
def no_callbacks?: () -> bool
private
def initialize: (Numeric interval) -> void
end
end
end