class Cutoff

Constants

CURRENT_STACK_KEY

Attributes

allowed_seconds[R]

@return [Float] The total number of seconds for this cutoff

Public Class Methods

checkpoint!() click to toggle source

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_all() click to toggle source

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
current() click to toggle source

Get the current {Cutoff} if one is set

# File lib/cutoff.rb, line 16
def current
  Thread.current[CURRENT_STACK_KEY]&.last
end
disable!() click to toggle source

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
disabled?() click to toggle source

True if cutoff was disabled with {#disable!}

@return [Boolean] True if disabled

# File lib/cutoff.rb, line 112
def disabled?
  @disabled == true
end
enable!() click to toggle source

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
new(allowed_seconds) click to toggle source

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
start(seconds) click to toggle source

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
stop(cutoff = nil) click to toggle source

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
version() click to toggle source

@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(seconds) { |cutoff| ... } click to toggle source

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

checkpoint!() click to toggle source

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
elapsed_seconds() click to toggle source

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
exceeded?() click to toggle source

Has the Cutoff been exceeded?

@return [Boolean] True if the timer expired

# File lib/cutoff.rb, line 156
def exceeded?
  seconds_remaining.negative?
end
ms_remaining() click to toggle source

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
seconds_remaining() click to toggle source

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