Skip to content

Permit disabling fail safe #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,20 @@ Kredis::Connections.connections[:shared] = Redis.new(

The above code could be added to either `config/environments/production.rb` or an initializer. Please ensure that your client private key, if used, is stored your credentials file or another secure location.

### Configure how the redis client is created
### Configuration

You can configure how the redis client is created by setting `config.kredis.connector` in your `application.rb`:

```ruby
config.kredis.connector = ->(config) { SomeRedisProxy.new(config) }
```

The fail-safe mechanism supports silently rescuing or returning a default value in the event that the Redis client returns an error (e.g. Redis is down). You can disable the default fail-safe mechanism:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering what kind of guidance to share with users here and realizing this is our first mention of fail-safe behavior—and of error handling at all! 😆

Which leads to some broader reflection that a global, config-level flag that changes internal behavior is hard to reason about or explain.

Continuing in review comment…


```ruby
config.kredis.fail_safe = false
```

By default Kredis will use `Redis.new(config)`.

## License
Expand Down
4 changes: 4 additions & 0 deletions lib/kredis/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class Kredis::Railtie < ::Rails::Railtie

initializer "kredis.configuration" do
Kredis::Connections.connector = config.kredis.connector || ->(config) { Redis.new(config) }

unless config.kredis.fail_safe.nil? do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing do

Kredis::Types::Proxy::Failsafe.enabled = config.kredis.fail_safe
end
end

initializer "kredis.configurator" do
Expand Down
41 changes: 23 additions & 18 deletions lib/kredis/types/proxy/failsafe.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
module Kredis::Types::Proxy::Failsafe
def initialize(*)
super
@fail_safe_suppressed = false
end
extend ActiveSupport::Concern

def failsafe
yield
rescue Redis::BaseError
raise if fail_safe_suppressed?
end
mattr_accessor :enabled, default: true

def suppress_failsafe_with(returning: nil)
old_fail_safe_suppressed, @fail_safe_suppressed = @fail_safe_suppressed, true
yield
rescue Redis::BaseError
returning
ensure
@fail_safe_suppressed = old_fail_safe_suppressed
def failsafe(returning: nil, &block)
if enabled? && !suppressed?
rescue_redis_errors_with(returning: returning, &block)
else
yield
end
end

private
def fail_safe_suppressed?
@fail_safe_suppressed
def enabled?
enabled
end

def suppressed?
@suppressed
end

def rescue_redis_errors_with(returning: nil)
old_suppressed, @suppressed = @suppressed, true
yield
rescue Redis::BaseError
returning
ensure
@suppressed = old_suppressed
end
end
6 changes: 2 additions & 4 deletions lib/kredis/types/proxying.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
class Kredis::Types::Proxying
attr_accessor :proxy, :key

delegate :failsafe, to: :proxy

def self.proxying(*commands)
delegate *commands, to: :proxy
end
Expand All @@ -13,10 +15,6 @@ def initialize(redis, key, **options)
options.each { |key, value| send("#{key}=", value) }
end

def failsafe(returning: nil, &block)
proxy.suppress_failsafe_with(returning: returning, &block)
end

private
delegate :type_to_string, :string_to_type, :types_to_strings, :strings_to_types, to: :Kredis
end
9 changes: 9 additions & 0 deletions test/proxy_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class ProxyTest < ActiveSupport::TestCase
setup { @proxy = Kredis.proxy "something" }
teardown { Kredis::Types::Proxy::Failsafe.enabled = true }

test "proxy set and get and del" do
@proxy.set "one"
Expand All @@ -19,4 +20,12 @@ class ProxyTest < ActiveSupport::TestCase
assert @proxy.set("two")
stub_redis_down(@proxy) { assert_nil @proxy.set("two") }
end

test "with fail safe disabled an error is raised" do
Kredis::Types::Proxy::Failsafe.enabled = false

stub_redis_down(@proxy) do
assert_raises(Redis::BaseError) { @proxy.get }
end
end
end