Sha256: 188d4262c7770de75435441729b5879653fb8a09ba39d437ccfe8b5fe694594a

Contents?: true

Size: 1.99 KB

Versions: 1

Compression:

Stored size: 1.99 KB

Contents

require 'rest-core/middleware'

require 'timeout'

class RestCore::Timeout
  def self.members; [:timeout]; end
  include RestCore::Middleware

  def call env
    return app.call(env) if env[DRY]
    monitor(env){ |e| app.call(e) }
  end

  def monitor env
    class_name = case name = run.class.to_s
                 when /Auto/
                   run.http_client.class.to_s
                 else
                   name
                 end

    case class_name
    when /Coolio|EmHttpRequest/
      if root_fiber? && env[ASYNC]
        yield(env.merge(TIMER => timeout_with_callback(env, class_name)))
      else
        yield(env.merge(TIMER => timeout_with_resume(  env, class_name)))
      end
    else
      ::Timeout.timeout(timeout(env)){ yield(env) }
    end
  end

  def root_fiber?
    if RestCore.const_defined?(:RootFiber)
      RootFiber == Fiber.current
    else
      true
    end
  end

  def timeout_with_callback env, class_name
    case class_name
    when /Coolio/
      timer = CoolioTimer.new(timeout(env))
      timer.error = timeout_error
      timer.attach(::Coolio::Loop.default)
      timer
    when /EmHttpRequest/
      EventMachineTimer.new(timeout(env), timeout_error)
    else
      raise "BUG: #{run} is not supported"
    end
  end

  def timeout_with_resume env, class_name
    case class_name
    when /Coolio/
      f = Fiber.current
      timer = CoolioTimer.new(timeout(env))
      error = timer.error = timeout_error
      timer.on_timer{ f.resume(error) if f.alive? }
      timer.attach(::Coolio::Loop.default)
      timer

    when /EmHttpRequest/
      f = Fiber.current
      EventMachineTimer.new(timeout(env), error = timeout_error){
        f.resume(error) if f.alive?
      }
    else
      raise "BUG: #{run} is not supported"
    end
  end

  def timeout_error
    ::Timeout::Error.new('execution expired')
  end

  autoload       :CoolioTimer,
    'rest-core/middleware/timeout/coolio_timer'
  autoload :EventMachineTimer,
    'rest-core/middleware/timeout/eventmachine_timer'
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rest-core-1.0.0 lib/rest-core/middleware/timeout.rb