Class: Rack::Idempotent

Inherits:
Object
  • Object
show all
Defined in:
lib/rack-idempotent/version.rb,
lib/rack-idempotent.rb

Defined Under Namespace

Classes: DefaultRescue, ExponentialBackoff, HTTPException, ImmediateRetry, RetryLimitExceeded, Retryable

Constant Summary collapse

VERSION =
"0.1.0"
DEFAULT_RETRY_LIMIT =
5

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ Idempotent

Returns a new instance of Idempotent.



20
21
22
23
24
# File 'lib/rack-idempotent.rb', line 20

def initialize(app, options={})
  @app           = app
  @retry_policy  = options[:retry] || Rack::Idempotent::ImmediateRetry.new
  @rescue_policy = options[:rescue] || Rack::Idempotent::DefaultRescue.new
end

Instance Attribute Details

#rescue_policyObject (readonly)

Returns the value of attribute rescue_policy.



18
19
20
# File 'lib/rack-idempotent.rb', line 18

def rescue_policy
  @rescue_policy
end

#retry_policyObject (readonly)

Returns the value of attribute retry_policy.



18
19
20
# File 'lib/rack-idempotent.rb', line 18

def retry_policy
  @retry_policy
end

Instance Method Details

#call(env) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/rack-idempotent.rb', line 26

def call(env)
  request = Rack::Request.new(env)
  response = nil
  exception = nil
  while true
    retry_policy.call(request, response, exception) if response || exception
    response, exception = nil

    begin
      status, headers, body = @app.call(env.dup)
      raise HTTPException.new(status, headers, body, request) if status >= 400
      response = Rack::Response.new(body, status, headers)
      next if rescue_policy.call({:response => response, :request => request})
      return [status, headers, body]
    rescue Rack::Idempotent::Retryable => exception
      request.env["idempotent.requests.exceptions"] ||= []
      request.env["idempotent.requests.exceptions"] << exception
      next
    rescue => exception
      if rescue_policy.call({:exception => exception, :request => request})
        request.env["idempotent.requests.exceptions"] ||= []
        request.env["idempotent.requests.exceptions"] << exception
        next
      end
      raise
    end
  end
end