Module: TIMEx::AutoCheck

Extended by:
AutoCheck
Included in:
AutoCheck
Defined in:
lib/timex/auto_check.rb

Overview

Note:

:line events are expensive; expect noticeable overhead on tight loops. Prefer explicit #Deadline#Deadline#check! for hot paths.

Note:

TracePoint does not fire inside C-native methods (+Mutex#synchronize+, blocking IO, etc.); pair with an IO-aware strategy for those regions.

Note:

Only target_thread: is traced; child threads need their own setup or explicit deadline checks.

Best-effort cooperative deadline checks driven by TracePoint (+:line+ and :b_return). Injects periodic #Deadline#Deadline#check! calls without requiring manual probes inside the block.

Constant Summary collapse

EVENTS =

Only Ruby-level events: :line already polls between every Ruby statement, and :b_return adds coverage at block boundaries so we interrupt promptly between iterations. :c_return was tempting but fires on every C method return (Hash#[], String#+, …) — the dispatch cost dwarfs the latency win on any non-trivial loop body.

%i[line b_return].freeze

Instance Method Summary collapse

Instance Method Details

#run(deadline, interval: TIMEx.config.auto_check_interval) {|deadline| ... } ⇒ Object

Runs block with TracePoint-driven deadline checks every interval Ruby events.

Parameters:

  • deadline (Deadline)
  • interval (Integer) (defaults to: TIMEx.config.auto_check_interval)

    line/block events between checks (from config by default)

Yield Parameters:

Returns:

  • (Object)

    the block's return value

Raises:

  • (Expired)

    when the deadline elapses between checks



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/timex/auto_check.rb', line 37

def run(deadline, interval: TIMEx.config.auto_check_interval)
  return yield(deadline) if deadline.infinite?

  counter = 0
  tp = TracePoint.new(*EVENTS) do |_event|
    counter += 1
    next unless counter >= interval

    counter = 0
    next if Thread.current.thread_variable_get(:timex_shielded)
    next unless deadline.expired?

    tp.disable
    deadline.check!(strategy: :cooperative)
  end

  tp.enable(target_thread: Thread.current) do
    yield(deadline)
  end
end