Class: TIMEx::Strategies::Base

Inherits:
Object
  • Object
show all
Includes:
NamedComponent, TimeoutHandling
Defined in:
lib/timex/strategies/base.rb

Overview

Abstract strategy: runs user code against a Deadline and maps Expired to on_timeout: behavior via TimeoutHandling.

Subclasses implement #run. Telemetry wraps each invocation when a non-null adapter is configured.

Direct Known Subclasses

Closeable, Cooperative, IO, Ractor, Subprocess, Unsafe, Wakeup

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.call(deadline:, on_timeout: :raise, **opts) {|deadline| ... } ⇒ Object

Convenience constructor: new(**opts).call(...).

Parameters:

  • deadline (Deadline, Numeric, Time, nil)

    budget or absolute deadline

  • on_timeout (Symbol, Proc) (defaults to: :raise)

    timeout dispatch mode

  • opts (Hash{Symbol => Object})

    subclass-specific options forwarded to #initialize

Yield Parameters:

  • deadline (Deadline)

    coerced deadline passed to user block

Returns:



27
28
29
# File 'lib/timex/strategies/base.rb', line 27

def call(deadline:, on_timeout: :raise, **opts, &block)
  new(**opts).call(deadline:, on_timeout:, &block)
end

Instance Method Details

#call(deadline:, on_timeout: :raise) {|deadline| ... } ⇒ Object

Coerces deadline, optionally instruments, and runs #run.

Parameters:

  • deadline (Deadline, Numeric, Time, nil)
  • on_timeout (Symbol, Proc) (defaults to: :raise)

Yield Parameters:

Returns:

  • (Object)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/timex/strategies/base.rb', line 39

def call(deadline:, on_timeout: :raise, &block)
  deadline = Deadline.coerce(deadline)

  # Resolve the adapter exactly once per call. `Telemetry.adapter` walks
  # `Telemetry.@adapter || TIMEx.config.telemetry_adapter || ...` on
  # every access; we hand the resolved object straight to `instrument`
  # to avoid re-walking it under the hot-path null check.
  adapter = TIMEx::Telemetry.adapter
  return run_unobserved(deadline, on_timeout, &block) if adapter.is_a?(TIMEx::Telemetry::Adapters::Null)

  deadline_ms = deadline.infinite? ? nil : deadline.remaining_ms.round
  TIMEx::Telemetry.instrument(
    event: "strategy.call",
    strategy: self.class.name_symbol,
    deadline_ms:
  ) do |payload|
    run(deadline, &block)
  rescue Expired => e
    payload[:outcome] = :timeout
    handle_timeout(on_timeout, e)
  end
end