Module: Philiprehberger::TimeoutKit

Defined in:
lib/philiprehberger/timeout_kit.rb,
lib/philiprehberger/timeout_kit/version.rb,
lib/philiprehberger/timeout_kit/deadline.rb

Defined Under Namespace

Classes: Deadline, DeadlineExceeded, Error

Constant Summary collapse

VERSION =
'0.3.0'

Class Method Summary collapse

Class Method Details

.cooperative(seconds) {|timeout| ... } ⇒ Object

Execute a block with a cooperative timeout. The block receives a timeout context that can be checked at safe cancellation points.

Unlike deadline, this is a simpler wrapper that does not support nesting.

Parameters:

  • seconds (Numeric)

    the number of seconds for the timeout

Yields:

  • (timeout)

    the block to execute within the timeout

Yield Parameters:

  • timeout (Deadline)

    a deadline-like context for checking timeout

Returns:

  • the block’s return value

Raises:



53
54
55
56
# File 'lib/philiprehberger/timeout_kit.rb', line 53

def self.cooperative(seconds)
  dl = Deadline.new(seconds)
  yield dl
end

.current_deadlineDeadline?

Return the current innermost deadline, or nil if none is active.

Returns:



61
62
63
64
# File 'lib/philiprehberger/timeout_kit.rb', line 61

def self.current_deadline
  stack = Thread.current[:philiprehberger_timeout_kit_deadlines]
  stack&.last
end

.deadline(seconds, name: nil, grace: nil, on_expire: nil) {|deadline| ... } ⇒ Object

Execute a block with a deadline. The block receives a Deadline object that can be used to check remaining time and whether the deadline has passed.

Deadlines can be nested. The innermost deadline is always the tightest constraint, but outer deadlines are also checked.

Parameters:

  • seconds (Numeric)

    the number of seconds for the deadline

  • name (String, nil) (defaults to: nil)

    optional human-readable name for the deadline

  • grace (Numeric, nil) (defaults to: nil)

    optional grace period in seconds after the primary deadline

  • on_expire (Proc, nil) (defaults to: nil)

    optional callback that fires once when expiry is detected

Yields:

  • (deadline)

    the block to execute within the deadline

Yield Parameters:

  • deadline (Deadline)

    the deadline context

Returns:

  • the block’s return value

Raises:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/philiprehberger/timeout_kit.rb', line 24

def self.deadline(seconds, name: nil, grace: nil, on_expire: nil, &block)
  dl = Deadline.new(seconds, name: name, grace: grace, on_expire: on_expire)

  # Support nested deadlines: use the tightest constraint
  parent = current_deadline
  effective = if parent && parent.expires_at < dl.expires_at
                parent
              else
                dl
              end

  push_deadline(effective)
  begin
    block.call(effective)
  ensure
    pop_deadline
  end
end