Class: TTY::Prompt::Timeout

Inherits:
Object
  • Object
show all
Defined in:
lib/tty/prompt/timeout.rb

Constant Summary collapse

Error =
Class.new(RuntimeError)
TIMEOUT_HANDLER =
proc { |t| t.raise Error, 'timeout expired' }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Timeout

Returns a new instance of Timeout.



12
13
14
15
16
17
18
# File 'lib/tty/prompt/timeout.rb', line 12

def initialize(options = {})
  @timeout_handler  = options.fetch(:timeout_handler) { TIMEOUT_HANDLER }
  @interval_handler = options.fetch(:interval_handler) { proc {} }
  @lock    = Mutex.new
  @running = true
  @timers  = Timers::Group.new
end

Class Method Details

.timeout(time, interval, &block) ⇒ Object



20
21
22
# File 'lib/tty/prompt/timeout.rb', line 20

def self.timeout(time, interval, &block)
  (@scheduler ||= new).timeout(time, interval, &block)
end

Instance Method Details

#async_run(time, interval) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/tty/prompt/timeout.rb', line 38

def async_run(time, interval)
  Thread.new do
    Thread.current.abort_on_exception = true
    start = Time.now

    interval_timer = @timers.every(interval) do
      runtime = Time.now - start
      delta = time - runtime
      if delta.round >= 0
        @interval_handler.(delta.round)
      end
    end

    while @running
      @lock.synchronize {
        @timers.wait
        runtime = Time.now - start
        delta = time - runtime

        if delta <= 0.0
          @timeout_handler.(Thread.current)
          break
        end
      }
    end

    interval_timer.cancel
  end
end

#timeout(time, interval, &block) ⇒ Object

Evalute block and time it

Parameters:

  • time (Float)

    the time by which to stop

  • interval (Float)

    the interval time for each tick



32
33
34
35
36
# File 'lib/tty/prompt/timeout.rb', line 32

def timeout(time, interval, &block)
  @runner = async_run(time, interval)
  @running = block.()
  @runner.join
end