flipper-fallback 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d348aae14d3835102e2e6f3cdbe4dbe349a773a5
4
- data.tar.gz: a148a40a28bcbc21b8be31bf72fabfe3ce37fbcc
3
+ metadata.gz: 72e22e996ecb958f8d9204b4706dd925de7f6946
4
+ data.tar.gz: 2b9ec63f46d922af3724107f81978126935a45a7
5
5
  SHA512:
6
- metadata.gz: 3402c8cba68227f6c3d979b07b71f810921ba41affaf49f679ab9e587ba6535e3a25eb1126ab71f655360514868e40dcc22109add286f1866d184ee1096bdc36
7
- data.tar.gz: eb2436868fd66066b25286f8c4cf0ce1dacd4bd8849de03df48b6e73f86632c4b1b3d1771b8ba727edef72c193bfda795d6dd3751a803ae537d39ab0c6435767
6
+ metadata.gz: b3d2de1ebd7064194bb1afc1a836fdb44e1bb61f0b28fad1737fbf76f86aabd2d6545a58f58fe27e1c0350c17126100bc49f34716ee9d4cd0295a6e3e5a2893d
7
+ data.tar.gz: fc0b8fa00eb954da53b79b3dd20e4b62c5077383cdd38cbcec422c2a8f2f7d9da2324c49d617b5704c16b786b337a46c206bd7572a3bb089d63503b8686443c0
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Flipper::Fallback
2
2
 
3
- TODO: Write a gem description
3
+ This gem lets you utilize multiple flipper adapters by providing a fall back pattern.
4
+ If the primary adapter fails by throwing an exception, the secondary adapter will be called.
5
+ By default, the fall back adapter is the in memory adapter which should not fail.
6
+ However, by default, the memory adapter is empty and ***everything will fail closed***
4
7
 
5
8
  ## Installation
6
9
 
@@ -18,7 +21,56 @@ Or install it yourself as:
18
21
 
19
22
  ## Usage
20
23
 
21
- TODO: Write usage instructions here
24
+ Basic usage might look like this
25
+ ```ruby
26
+ require 'flipper/adapters/redis'
27
+ require 'flipper/adapters/fallback'
28
+
29
+ flipper_adapter ||= Flipper::Adapters::Fallback.new(Flipper::Adapters::Redis.new(App.redis))
30
+ @flipper ||= Flipper.new(flipper_adapter)
31
+ ```
32
+
33
+ If you wanted to set how things will fail, you should be able to do something like this.
34
+ ```ruby
35
+ # Untested
36
+ # Please give me a better example of how one might do this
37
+ memory = Flipper::Adapters::Memory.new()
38
+ template = Flipper.new(memory)
39
+ template[:search].enable
40
+ template[:experimental].disable
41
+
42
+ # Template has modified our "memory" adapter to how we want
43
+ adapter = Flipper::Adapters::Fallback.new(Flipper::Adapters::Redis.new(App.redis), options = {}, memory)
44
+ ```
45
+
46
+ Advanced usage might look like this
47
+ ```ruby
48
+ error_handler = lambda do |error, primary_adapter, fallback_adapter|
49
+ # Keep stats on how many and what kind of error we are seeing
50
+ # There is probably a better way to do this
51
+ statsd.increment("flipper.#{primary_adapter.name}.errors.#{error.to_s.gsub('.','_')}")
52
+ end
53
+
54
+ # Throw a timeout exception if we take more than 2 seconds.
55
+ # Timeout wraps both the primary and fallback adapters.
56
+ # If the primary adapter takes longer than 2 seconds, we won't even try the fallback
57
+ timeout_in_seconds = 2
58
+
59
+ flipper_adapter ||= Flipper::Adapters::Fallback.new(Flipper::Adapters::Redis.new(App.redis), :on_error => error_handler, :timeout => timeout_in_seconds)
60
+ @flipper ||= Flipper.new(flipper_adapter)
61
+ ```
62
+
63
+ Some "creative" usage might look like this
64
+ ```ruby
65
+ # Untested
66
+ # Make a list of adapters to try
67
+ head = Flipper::Adapters::Fallback.new(Flipper::Adapters::Memcache.new(Rails.cache))
68
+ head = Flipper::Adapters::Fallback.new(Flipper::Adapters::Redis.new(App.redis), { :timeout => 1 }, head)
69
+ head = Flipper::Adapters::Fallback.new(Flipper::Adapters::ElasticSearch.new(App.search), { :timeout => 1 }, head)
70
+
71
+ # This would try ES -> Redis -> Memcache -> Memory.
72
+ @flipper ||= Flipper.new(head)
73
+ ```
22
74
 
23
75
  ## Contributing
24
76
 
@@ -1,25 +1,37 @@
1
1
  require 'flipper'
2
2
  require 'flipper/adapters/memory'
3
3
  require 'delegate'
4
+ require 'timeout'
4
5
 
5
6
  module Flipper
6
7
  module Adapters
7
8
  class Fallback < SimpleDelegator
8
- VERSION = '0.0.2'
9
- def initialize(primary_adapter, fallback_adapter = Flipper::Adapters::Memory.new)
9
+ VERSION = '0.1.0'
10
+
11
+ def initialize(primary_adapter, options = {}, fallback_adapter = Flipper::Adapters::Memory.new)
10
12
  super(primary_adapter)
11
13
  @primary_adapter = primary_adapter
12
14
  @fallback_adapter = fallback_adapter
13
15
 
14
16
  @delegate_sd_obj = primary_adapter
17
+
18
+ @on_error = options[:on_error] || lambda do |error, primary_adapter, fallback_adapter|
19
+ STDERR.puts("[Flipper::Adapters::Fallback] Primary adapter(#{primary_adapter.inspect}) Failure! #{error}")
20
+ STDERR.puts("[Flipper::Adapters::Fallback] Falling back to #{fallback_adapter.inspect})")
21
+ end
22
+
23
+ @timeout = options[:timeout]
15
24
  end
16
25
 
17
26
  def method_missing(m, *args, &block)
18
- super
19
- rescue => e
20
- STDERR.puts("[Flipper::Adapters::Fallback] Primary adapter(#{@primary_adapter.inspect}) Failure! #{e}")
21
- STDERR.puts("[Flipper::Adapters::Fallback] Falling back to #{@fallback_adapter.inspect})")
22
- @fallback_adapter.__send__(m, *args, &block)
27
+ Timeout::timeout(@timeout) do
28
+ begin
29
+ super
30
+ rescue => error
31
+ @on_error.call(error, @primary_adapter, @fallback_adapter)
32
+ @fallback_adapter.__send__(m, *args, &block)
33
+ end
34
+ end
23
35
  end
24
36
  end
25
37
  end
@@ -35,7 +35,12 @@ describe Flipper::Adapters::Fallback do
35
35
  Redis.new(options)
36
36
  }
37
37
 
38
- subject { described_class.new(Flipper::Adapters::Redis.new(client)) }
38
+ let(:on_error) do
39
+ lambda do |error, primary_adapter, fallback_adapter|
40
+ # noop
41
+ end
42
+ end
43
+ subject { described_class.new(Flipper::Adapters::Redis.new(client), { :on_error => on_error, :timeout => 0.1 }) }
39
44
 
40
45
  it_should_behave_like 'a flipper adapter'
41
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-fallback
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Lundquist
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-26 00:00:00.000000000 Z
11
+ date: 2014-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: flipper