File: timeout.rb

package info (click to toggle)
ruby-rack-timeout 0.7.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212 kB
  • sloc: ruby: 515; makefile: 4
file content (28 lines) | stat: -rw-r--r-- 1,591 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
require_relative "namespace"
require_relative "scheduler"

class Rack::Timeout::Scheduler::Timeout
  class Error < RuntimeError; end
  ON_TIMEOUT = ->thr { thr.raise Error, "execution expired" } # default action to take when a timeout happens

  # initializes a timeout object with an optional block to handle the timeout differently. the block is passed the thread that's gone overtime.
  def initialize(&on_timeout)
    @on_timeout = on_timeout || ON_TIMEOUT
    @scheduler  = Rack::Timeout::Scheduler.singleton
  end

  # takes number of seconds to wait before timing out, and code block subject to time out
  def timeout(secs, &block)
    return block.call if secs.nil? || secs.zero?            # skip timeout flow entirely for zero or nil
    thr = Thread.current                                    # reference to current thread to be used in timeout thread
    job = @scheduler.run_in(secs) { @on_timeout.call thr }  # schedule this thread to be timed out; should get cancelled if block completes on time
    return block.call                                       # do what you gotta do
  ensure                                                    #
    job.cancel! if job                                      # cancel the scheduled timeout job; if the block completed on time, this
  end                                                       # will get called before the timeout code's had a chance to run.

  # timeout method on singleton instance for when a custom on_timeout is not required
  def self.timeout(secs, &block)
    (@singleton ||= new).timeout(secs, &block)
  end
end