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

Methods included from NamedComponent

included

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