class Cutoff
Constants
- CURRENT_STACK_KEY
Attributes
@return [Float] The total number of seconds for this cutoff
Public Class Methods
Raise an exception if there is an active expired cutoff
Does nothing if no active cutoff is set
@raise CutoffExceededError
If there is an active expired cutoff @return [void]
# File lib/cutoff.rb, line 84 def checkpoint! cutoff = current return unless cutoff cutoff.checkpoint! end
Clear the entire stack for this thread
@return [void]
# File lib/cutoff.rb, line 58 def clear_all Thread.current[CURRENT_STACK_KEY] = nil end
Get the current {Cutoff} if one is set
# File lib/cutoff.rb, line 16 def current Thread.current[CURRENT_STACK_KEY]&.last end
Disable Cutoff
globally. Useful for testing and debugging
Should not be used in production
@return [void]
# File lib/cutoff.rb, line 96 def disable! @disabled = true end
True if cutoff was disabled with {#disable!}
@return [Boolean] True if disabled
# File lib/cutoff.rb, line 112 def disabled? @disabled == true end
Enable Cutoff
globally if it has been disabled
Should not be used in production
@return [void]
# File lib/cutoff.rb, line 105 def enable! @disabled = false end
Create a new cutoff
The timer starts immediately upon creation
@param allowed_seconds
[Integer, Float] The total number of seconds to allow
# File lib/cutoff.rb, line 125 def initialize(allowed_seconds) @allowed_seconds = allowed_seconds.to_f @start_time = Cutoff.now end
Add a new {Cutoff} to the stack
This {Cutoff} will be specific to this thread
If a cutoff is already started for this thread, then `start` uses the minimum of the current remaining time and the given time
@param seconds [Float, Integer] The number of seconds for the cutoff. May
be overridden if there is an active cutoff and it has less remaining time.
@return [Cutoff] The {Cutoff} instance
# File lib/cutoff.rb, line 31 def start(seconds) seconds = [seconds, current.seconds_remaining].min if current cutoff = Cutoff.new(seconds) Thread.current[CURRENT_STACK_KEY] ||= [] Thread.current[CURRENT_STACK_KEY] << cutoff cutoff end
Remove the top {Cutoff} from the stack
@param cutoff [Cutoff] If given, the top instance will only be removed
if it matches the given cutoff instance
@return [Cutoff, nil] If a cutoff was removed it is returned
# File lib/cutoff.rb, line 44 def stop(cutoff = nil) stack = Thread.current[CURRENT_STACK_KEY] return unless stack top = stack.last stack.pop if cutoff.nil? || top == cutoff clear_all if stack.empty? cutoff end
@return [Gem::Version] The current version of the cutoff gem
# File lib/cutoff/version.rb, line 5 def self.version Gem::Version.new('0.3.0') end
Wrap a block in a cutoff
Same as calling {.start} and {.stop} manually, but safer since you can't forget to stop a cutoff and it handles exceptions raised inside the block
@see .start @see .stop @return The value that returned from the block
# File lib/cutoff.rb, line 71 def wrap(seconds) cutoff = start(seconds) yield cutoff ensure stop(cutoff) end
Public Instance Methods
Raises an error if this Cutoff
has been exceeded
@raise CutoffExceededError
If there is an active expired cutoff @return [void]
# File lib/cutoff.rb, line 164 def checkpoint! raise CutoffExceededError, self if exceeded? nil end
The number of seconds elapsed since this {Cutoff} was created
@return [Float] The number of seconds
# File lib/cutoff.rb, line 147 def elapsed_seconds return 0 if Cutoff.disabled? Cutoff.now - @start_time end
Has the Cutoff
been exceeded?
@return [Boolean] True if the timer expired
# File lib/cutoff.rb, line 156 def exceeded? seconds_remaining.negative? end
The number of milliseconds left on the clock
@return [Float] The number of milliseconds
# File lib/cutoff.rb, line 140 def ms_remaining seconds_remaining * 1000 end
The number of seconds left on the clock
@return [Float] The number of seconds
# File lib/cutoff.rb, line 133 def seconds_remaining @allowed_seconds - elapsed_seconds end