Class: Berater::Middleware::FailOpen

Inherits:
Object
  • Object
show all
Defined in:
lib/berater/middleware/fail_open.rb

Constant Summary collapse

ERRORS =
Set[
  Redis::BaseConnectionError,
]

Instance Method Summary collapse

Constructor Details

#initialize(errors: nil, on_fail: nil) ⇒ FailOpen

Returns a new instance of FailOpen.



10
11
12
13
# File 'lib/berater/middleware/fail_open.rb', line 10

def initialize(errors: nil, on_fail: nil)
  @errors = errors || ERRORS
  @on_fail = on_fail
end

Instance Method Details

#call(**opts) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/berater/middleware/fail_open.rb', line 15

def call(*, **opts)
  yield.tap do |lock|
    return lock unless lock&.is_a?(Berater::Lock)

    # wrap lock.release so it fails open

    # save reference to original function
    release_fn = lock.method(:release)

    # make bound variables accessible to block
    errors = @errors
    on_fail = @on_fail

    lock.define_singleton_method(:release) do
      release_fn.call
    rescue *errors => e
      on_fail&.call(e)
      false
    end
  end
rescue *@errors => e
  @on_fail&.call(e)

  # fail open by faking a lock
  Berater::Lock.new(opts[:capacity], -1)
end