class IdempotentRequest::Middleware
Attributes
app[R]
config[R]
env[R]
notifier[R]
policy[R]
request[R]
Public Class Methods
new(app, config = {})
click to toggle source
# File lib/idempotent-request/middleware.rb, line 3 def initialize(app, config = {}) @app = app @config = config @policy = config.fetch(:policy) @notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications) @conflict_response_status = config.fetch(:conflict_response_status, 429) end
Public Instance Methods
call(env)
click to toggle source
# File lib/idempotent-request/middleware.rb, line 11 def call(env) # dup the middleware to be thread-safe dup.process(env) end
process(env)
click to toggle source
# File lib/idempotent-request/middleware.rb, line 16 def process(env) set_request(env) request.env['idempotent.request'] = {} return app.call(request.env) unless process? request.env['idempotent.request']['key'] = request.key response = read_idempotent_request || write_idempotent_request || concurrent_request_response instrument(request) response end
Private Instance Methods
concurrent_request_response()
click to toggle source
# File lib/idempotent-request/middleware.rb, line 48 def concurrent_request_response status = @conflict_response_status headers = { 'Content-Type' => 'application/json' } body = [ Oj.dump('error' => 'Concurrent requests detected') ] request.env['idempotent.request']['concurrent_request_response'] = true Rack::Response.new(body, status, headers).finish end
instrument(request)
click to toggle source
# File lib/idempotent-request/middleware.rb, line 67 def instrument(request) notifier.instrument('idempotent.request', request: request) if notifier end
process?()
click to toggle source
# File lib/idempotent-request/middleware.rb, line 58 def process? !request.key.to_s.empty? && should_be_idempotent? end
read_idempotent_request()
click to toggle source
# File lib/idempotent-request/middleware.rb, line 32 def read_idempotent_request request.env['idempotent.request']['read'] = storage.read end
set_request(env)
click to toggle source
# File lib/idempotent-request/middleware.rb, line 71 def set_request(env) @env = env @request ||= Request.new(env, config) end
should_be_idempotent?()
click to toggle source
# File lib/idempotent-request/middleware.rb, line 62 def should_be_idempotent? return false unless policy policy.new(request).should? end
storage()
click to toggle source
# File lib/idempotent-request/middleware.rb, line 28 def storage @storage ||= RequestManager.new(request, config) end
write_idempotent_request()
click to toggle source
# File lib/idempotent-request/middleware.rb, line 36 def write_idempotent_request return unless storage.lock begin result = app.call(request.env) request.env['idempotent.request']['write'] = result storage.write(*result) ensure request.env['idempotent.request']['unlocked'] = storage.unlock result end end