Class: Philiprehberger::TimeoutKit::Deadline
- Inherits:
-
Object
- Object
- Philiprehberger::TimeoutKit::Deadline
- Defined in:
- lib/philiprehberger/timeout_kit/deadline.rb
Overview
A cooperative deadline that tracks remaining time and supports nesting.
Deadlines do not use Thread.raise. Instead, callers must explicitly call #check! at safe cancellation points.
Instance Attribute Summary collapse
-
#expires_at ⇒ Float
readonly
The absolute monotonic time when the deadline expires.
-
#name ⇒ String?
readonly
The human-readable name for this deadline.
Instance Method Summary collapse
-
#check! ⇒ void
Check whether the deadline has expired.
-
#elapsed ⇒ Float
Return the number of seconds elapsed since the deadline was created.
-
#expired? ⇒ Boolean
Whether the primary deadline has expired.
-
#grace_remaining ⇒ Float
Return the remaining time in the grace period.
-
#in_grace? ⇒ Boolean
Whether the deadline is currently in the grace period.
-
#initialize(seconds, name: nil, grace: nil, on_expire: nil) ⇒ Deadline
constructor
Create a new deadline.
-
#on_expire { ... } ⇒ void
Register a callback that fires once when expiry is detected.
-
#remaining ⇒ Float
Return the remaining time in seconds until the primary deadline.
Constructor Details
#initialize(seconds, name: nil, grace: nil, on_expire: nil) ⇒ Deadline
Create a new deadline.
22 23 24 25 26 27 28 29 30 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 22 def initialize(seconds, name: nil, grace: nil, on_expire: nil) @started_at = now @expires_at = @started_at + seconds @name = name @grace_seconds = grace @grace_expires_at = @grace_seconds ? @expires_at + @grace_seconds : nil @on_expire = on_expire @expire_callback_fired = false end |
Instance Attribute Details
#expires_at ⇒ Float (readonly)
Returns the absolute monotonic time when the deadline expires.
11 12 13 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 11 def expires_at @expires_at end |
#name ⇒ String? (readonly)
Returns the human-readable name for this deadline.
14 15 16 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 14 def name @name end |
Instance Method Details
#check! ⇒ void
This method returns an undefined value.
Check whether the deadline has expired.
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 44 def check! return unless expired? fire_expire_callback # If we have a grace period and are still within it, don't raise return if in_grace? = @name ? "Deadline '#{@name}' exceeded" : 'Deadline exceeded' raise DeadlineExceeded, end |
#elapsed ⇒ Float
Return the number of seconds elapsed since the deadline was created. This is a pure wall-clock reading from the monotonic clock and continues to increase past the original budget after expiration. Independent of #expired? and #in_grace?.
75 76 77 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 75 def elapsed now - @started_at end |
#expired? ⇒ Boolean
Whether the primary deadline has expired.
92 93 94 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 92 def expired? now >= @expires_at end |
#grace_remaining ⇒ Float
Return the remaining time in the grace period.
82 83 84 85 86 87 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 82 def grace_remaining return 0.0 unless @grace_expires_at r = @grace_expires_at - now r.negative? ? 0.0 : r end |
#in_grace? ⇒ Boolean
Whether the deadline is currently in the grace period. True only when the primary deadline has expired but the grace period has not.
100 101 102 103 104 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 100 def in_grace? return false unless @grace_expires_at expired? && now < @grace_expires_at end |
#on_expire { ... } ⇒ void
This method returns an undefined value.
Register a callback that fires once when expiry is detected.
36 37 38 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 36 def on_expire(&block) @on_expire = block end |
#remaining ⇒ Float
Return the remaining time in seconds until the primary deadline. Can be negative during the grace period.
60 61 62 63 64 65 66 67 |
# File 'lib/philiprehberger/timeout_kit/deadline.rb', line 60 def remaining r = @expires_at - now if @grace_seconds r else r.negative? ? 0.0 : r end end |