flipper 0.22.2 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +6 -1
  3. data/.github/workflows/examples.yml +1 -0
  4. data/.rspec +1 -0
  5. data/Changelog.md +18 -2
  6. data/Gemfile +2 -2
  7. data/README.md +15 -67
  8. data/docs/README.md +1 -0
  9. data/docs/images/banner.jpg +0 -0
  10. data/lib/flipper/adapters/dual_write.rb +9 -15
  11. data/lib/flipper/adapters/failover.rb +83 -0
  12. data/lib/flipper/adapters/http/client.rb +11 -1
  13. data/lib/flipper/adapters/http/error.rb +19 -1
  14. data/lib/flipper/adapters/memoizable.rb +8 -16
  15. data/lib/flipper/adapters/pstore.rb +2 -5
  16. data/lib/flipper/adapters/sync/interval_synchronizer.rb +1 -6
  17. data/lib/flipper/adapters/sync.rb +9 -15
  18. data/lib/flipper/instrumenters/memory.rb +6 -2
  19. data/lib/flipper/version.rb +1 -1
  20. data/spec/flipper/actor_spec.rb +0 -2
  21. data/spec/flipper/adapter_spec.rb +0 -2
  22. data/spec/flipper/adapters/dual_write_spec.rb +0 -2
  23. data/spec/flipper/adapters/failover_spec.rb +129 -0
  24. data/spec/flipper/adapters/http_spec.rb +39 -3
  25. data/spec/flipper/adapters/instrumented_spec.rb +0 -2
  26. data/spec/flipper/adapters/memoizable_spec.rb +0 -2
  27. data/spec/flipper/adapters/memory_spec.rb +0 -3
  28. data/spec/flipper/adapters/operation_logger_spec.rb +0 -2
  29. data/spec/flipper/adapters/pstore_spec.rb +0 -2
  30. data/spec/flipper/adapters/read_only_spec.rb +0 -1
  31. data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +0 -1
  32. data/spec/flipper/adapters/sync/interval_synchronizer_spec.rb +4 -5
  33. data/spec/flipper/adapters/sync/synchronizer_spec.rb +0 -1
  34. data/spec/flipper/adapters/sync_spec.rb +0 -2
  35. data/spec/flipper/configuration_spec.rb +0 -1
  36. data/spec/flipper/dsl_spec.rb +0 -1
  37. data/spec/flipper/feature_check_context_spec.rb +0 -2
  38. data/spec/flipper/feature_spec.rb +0 -1
  39. data/spec/flipper/gate_spec.rb +0 -2
  40. data/spec/flipper/gate_values_spec.rb +0 -1
  41. data/spec/flipper/gates/actor_spec.rb +0 -2
  42. data/spec/flipper/gates/boolean_spec.rb +0 -2
  43. data/spec/flipper/gates/group_spec.rb +0 -2
  44. data/spec/flipper/gates/percentage_of_actors_spec.rb +0 -2
  45. data/spec/flipper/gates/percentage_of_time_spec.rb +0 -2
  46. data/spec/flipper/identifier_spec.rb +0 -1
  47. data/spec/flipper/instrumentation/log_subscriber_spec.rb +0 -1
  48. data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +0 -1
  49. data/spec/flipper/instrumenters/memory_spec.rb +18 -1
  50. data/spec/flipper/instrumenters/noop_spec.rb +14 -8
  51. data/spec/flipper/middleware/memoizer_spec.rb +0 -2
  52. data/spec/flipper/middleware/setup_env_spec.rb +0 -2
  53. data/spec/flipper/railtie_spec.rb +17 -19
  54. data/spec/flipper/registry_spec.rb +0 -1
  55. data/spec/flipper/typecast_spec.rb +0 -1
  56. data/spec/flipper/types/actor_spec.rb +0 -1
  57. data/spec/flipper/types/boolean_spec.rb +0 -1
  58. data/spec/flipper/types/group_spec.rb +0 -1
  59. data/spec/flipper/types/percentage_of_actors_spec.rb +0 -1
  60. data/spec/flipper/types/percentage_of_time_spec.rb +0 -1
  61. data/spec/flipper/types/percentage_spec.rb +0 -1
  62. data/spec/flipper_integration_spec.rb +0 -1
  63. data/spec/flipper_spec.rb +0 -1
  64. data/spec/{helper.rb → spec_helper.rb} +2 -1
  65. data/spec/support/spec_helpers.rb +2 -6
  66. metadata +10 -13
  67. data/docs/Adapters.md +0 -124
  68. data/docs/Caveats.md +0 -4
  69. data/docs/Gates.md +0 -167
  70. data/docs/Instrumentation.md +0 -27
  71. data/docs/Optimization.md +0 -137
  72. data/docs/api/README.md +0 -884
  73. data/docs/http/README.md +0 -36
  74. data/docs/read-only/README.md +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11758f40e5798d6592a7f810a32a501593f7a2a59322f8261b8d366c1686fc25
4
- data.tar.gz: b0f7713f289ef976328f12c31d3e9249251cb2bb196c7b324dcd952eafe00c88
3
+ metadata.gz: c7754b40752e0c255308fedfb6ef7784e7e9b3cf4ba0035a289a02074e61e4e7
4
+ data.tar.gz: 7e0add2ac95c2dc929a97fef218ece9fbc904c911ffe6f4ac1d3ccbc36befab9
5
5
  SHA512:
6
- metadata.gz: 35d55048b48cb80c10f8242cef4494224858d9bcbd7e8fb934fb12c6348ebb5538d239dad5eddfbf13fcc6cefe1e4e9eddaffecd053628d1390081b4bdf79857
7
- data.tar.gz: bf145e26dbf12f788d708a4a1b50b3684ce8d53b32a148ee8fde1b697e008ddd0a903a81f20a83b2b78bc270faa9470255e4700e1e8d08b01c905ae4906a8040
6
+ metadata.gz: 3e5b7b82f89f1cdbb93f0a07d6909aea686214e9ce6a7c1daf4661f900da5e3dfe3176ed89ffe1bb63b8317788bce1a662ad27b2e88b01bebb77856213be7f4d
7
+ data.tar.gz: e8d25c0ed393a34f4f7ec93b2d2ec8707f009ba35e83ef606d4850c7031bb7e923af83c2472fd2d6d00004d6561f410156021b7892dab20883dd0c6fe2efcb15
@@ -16,7 +16,12 @@ jobs:
16
16
  strategy:
17
17
  matrix:
18
18
  ruby: ['2.5', '2.6', '2.7']
19
- rails: ['5.2', '6.0.0', '6.1.0']
19
+ rails: ['5.2', '6.0.0', '6.1.0', '7.0.0']
20
+ exclude:
21
+ - ruby: "2.5"
22
+ rails: "7.0.0"
23
+ - ruby: "2.6"
24
+ rails: "7.0.0"
20
25
  env:
21
26
  SQLITE3_VERSION: 1.4.1
22
27
  REDIS_URL: redis://localhost:6379/0
@@ -2,6 +2,7 @@ name: Examples
2
2
  on: [push, pull_request]
3
3
  jobs:
4
4
  test:
5
+ if: github.repository_owner == 'jnunemaker'
5
6
  name: Test on ruby ${{ matrix.ruby }} and rails ${{ matrix.rails }}
6
7
  runs-on: ubuntu-latest
7
8
  services:
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Changelog.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 0.23.0
2
+
3
+ ### Additions/Changes
4
+
5
+ * Allow some HTML in banner and descriptions (https://github.com/jnunemaker/flipper/pull/570).
6
+ * Moved some cloud headers to http client (https://github.com/jnunemaker/flipper/pull/567).
7
+ * Update flipper-ui jquery and bootstrap versions (https://github.com/jnunemaker/flipper/issues/565 and https://github.com/jnunemaker/flipper/pull/566).
8
+ * Moved docs to www.flippercloud.io/docs (https://github.com/jnunemaker/flipper/pull/574).
9
+ * PStore adapter now defaults to thread safe and no longer supports `.thread_safe` (https://github.com/jnunemaker/flipper/commit/4048704fefe41b716015294a19a0b94546637630).
10
+ * Add failover adapter (https://github.com/jnunemaker/flipper/pull/584).
11
+ * Improve http adapter error message (https://github.com/jnunemaker/flipper/pull/587).
12
+ * Rails 7 support (mostly in https://github.com/jnunemaker/flipper/pull/592).
13
+
1
14
  ## 0.22.2
2
15
 
3
16
  ### Additions/Changes
@@ -35,7 +48,7 @@
35
48
  * Added cloud recommendation to flipper-ui. Can be disabled with `Flipper::UI.configure { |config| config.cloud_recommendation = false }`. Just want to raise awareness that more is available if people want it (https://github.com/jnunemaker/flipper/pull/504)
36
49
  * Added default `flipper_id` implementation via `Flipper::Identifier` and automatically included it in ActiveRecord and Sequel models (https://github.com/jnunemaker/flipper/pull/505)
37
50
  * Deprecate superflous sync_method setting (https://github.com/jnunemaker/flipper/pull/511)
38
- * Flipper is now pre-configured when used with Rails. By default, it will [memoize and preload all features for each request](docs/Optimization.md#memoization). (https://github.com/jnunemaker/flipper/pull/506)
51
+ * Flipper is now pre-configured when used with Rails. By default, it will [memoize and preload all features for each request](https://flippercloud.io/docs/optimization#memoization). (https://github.com/jnunemaker/flipper/pull/506)
39
52
 
40
53
  ### Upgrading
41
54
 
@@ -50,7 +63,7 @@ You should be able to upgrade to 0.21 without any breaking changes. However, if
50
63
  - end
51
64
  ```
52
65
 
53
- 2. `Flipper::Middleware::Memoizer` will be enabled by default.
66
+ 2. `Flipper::Middleware::Memoizer` will be enabled by default -- including preloading. **Note**: You may want to disable preloading (see below) if you have > 100 features.
54
67
 
55
68
  ```diff
56
69
  # config/initializers/flipper.rb
@@ -59,6 +72,9 @@ You should be able to upgrade to 0.21 without any breaking changes. However, if
59
72
  + Rails.application.configure do
60
73
  + # Uncomment to configure which features to preload on all requests
61
74
  + # config.flipper.preload = [:stats, :search, :some_feature]
75
+ + #
76
+ + # Or, you may want to disable preloading entirely:
77
+ + # config.flipper.preload = false
62
78
  + end
63
79
  ```
64
80
 
data/Gemfile CHANGED
@@ -13,11 +13,11 @@ gem 'statsd-ruby', '~> 1.2.1'
13
13
  gem 'rspec', '~> 3.0'
14
14
  gem 'rack-test', '~> 0.6.3'
15
15
  gem 'sqlite3', "~> #{ENV['SQLITE3_VERSION'] || '1.4.1'}"
16
- gem 'rails', "~> #{ENV['RAILS_VERSION'] || '6.0.0'}"
16
+ gem 'rails', "~> #{ENV['RAILS_VERSION'] || '7.0.0'}"
17
17
  gem 'minitest', '~> 5.8'
18
18
  gem 'minitest-documentation'
19
19
  gem 'webmock', '~> 3.0'
20
- gem 'climate_control'
20
+ gem 'ice_age'
21
21
  gem 'redis-namespace'
22
22
  gem 'webrick'
23
23
 
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  [![Flipper Mark](docs/images/banner.jpg)](https://www.flippercloud.io)
2
2
 
3
+ [Website](https://flippercloud.io) | [Documentation](https://flippercloud.io/docs) | [Examples](examples) | [Twitter](https://twitter.com/flipper_cloud)
4
+
3
5
  # Flipper
4
6
 
5
7
  > Beautiful, performant feature flags for Ruby.
@@ -19,7 +21,7 @@ Add this line to your application's Gemfile:
19
21
 
20
22
  gem 'flipper'
21
23
 
22
- You'll also want to pick a storage [adapter](#adapters), for example:
24
+ You'll also want to pick a storage [adapter](https://flippercloud.io/docs/adapters), for example:
23
25
 
24
26
  gem 'flipper-active_record'
25
27
 
@@ -31,6 +33,10 @@ Or install it yourself with:
31
33
 
32
34
  $ gem install flipper
33
35
 
36
+ ## Subscribe & Ship
37
+
38
+ [💌  Subscribe](https://buttondown.email/flipper) - I'll send you short and sweet emails when we release new versions.
39
+
34
40
  ## Getting Started
35
41
 
36
42
  Use `Flipper#enabled?` in your app to check if a feature is enabled.
@@ -46,74 +52,25 @@ end
46
52
 
47
53
  All features are disabled by default, so you'll need to explicitly enable them.
48
54
 
49
- #### Enable a feature for everyone
50
-
51
55
  ```ruby
56
+ # Enable a feature for everyone
52
57
  Flipper.enable :search
53
- ```
54
58
 
55
- #### Enable a feature for a specific actor
56
-
57
- ```ruby
59
+ # Enable a feature for a specific actor
58
60
  Flipper.enable_actor :search, current_user
59
- ```
60
-
61
- #### Enable a feature for a group of actors
62
61
 
63
- First tell Flipper about your groups:
64
-
65
- ```ruby
66
- # config/initializers/flipper.rb
67
- Flipper.register(:admin) do |actor|
68
- actor.respond_to?(:admin?) && actor.admin?
69
- end
70
- ```
71
-
72
- Then enable the feature for that group:
73
-
74
- ```ruby
62
+ # Enable a feature for a group of actors
75
63
  Flipper.enable_group :search, :admin
76
- ```
77
-
78
- #### Enable a feature for a percentage of actors
79
64
 
80
- ```ruby
65
+ # Enable a feature for a percentage of actors
81
66
  Flipper.enable_percentage_of_actors :search, 2
82
67
  ```
83
68
 
84
-
85
- Read more about enabling and disabling features with [Gates](docs/Gates.md). Check out the [examples directory](examples/) for more, and take a peek at the [DSL](lib/flipper/dsl.rb) and [Feature](lib/flipper/feature.rb) classes for code/docs.
86
-
87
- ## Adapters
88
-
89
- Flipper is built on adapters for maximum flexibility. Regardless of what data store you are using, Flipper can performantly store data in it.
90
-
91
- Pick one of our [supported adapters](docs/Adapters.md#officially-supported) and follow the installation instructions:
92
-
93
- * [Active Record](docs/active_record/README.md)
94
- * [Sequel](docs/sequel/README.md)
95
- * [Redis](docs/redis/README.md)
96
- * [Mongo](docs/mongo/README.md)
97
- * [Moneta](docs/moneta/README.md)
98
- * [Rollout](docs/rollout/README.md)
99
-
100
- Or [roll your own](docs/Adapters.md#roll-your-own). We even provide automatic (rspec and minitest) tests for you, so you know you've built your custom adapter correctly.
101
-
102
- Read more about [Adapters](docs/Adapters.md).
103
-
104
- ## Flipper UI
105
-
106
- If you prefer a web UI to an IRB console, you can setup the [Flipper UI](docs/ui/README.md).
107
-
108
- It's simple and pretty.
109
-
110
- ![Flipper UI Screenshot](docs/ui/images/feature.png)
111
-
112
-
69
+ Read more about [getting started with Flipper](https://flippercloud.io/docs) and [enabling features](https://flippercloud.io/docs/features).
113
70
 
114
71
  ## Flipper Cloud
115
72
 
116
- Or, (even better than OSS + UI) use [Flipper Cloud](https://www.flippercloud.io) which comes with:
73
+ Like Flipper and want more? Check out [Flipper Cloud](https://www.flippercloud.io), which comes with:
117
74
 
118
75
  * **everything in one place** — no need to bounce around from different application UIs or IRB consoles.
119
76
  * **permissions** — grant access to everyone in your organization or lockdown each project to particular people.
@@ -127,21 +84,11 @@ Or, (even better than OSS + UI) use [Flipper Cloud](https://www.flippercloud.io)
127
84
 
128
85
  Cloud is super simple to integrate with Rails ([demo app](https://github.com/fewerandfaster/flipper-rails-demo)), Sinatra or any other framework.
129
86
 
130
- ## Advanced
131
-
132
- A few miscellaneous docs with more info for the hungry.
133
-
134
- * [Instrumentation](docs/Instrumentation.md) - ActiveSupport::Notifications and Statsd
135
- * [Optimization](docs/Optimization.md) - Memoization middleware and Cache adapters
136
- * [API](docs/api/README.md) - HTTP API interface
137
- * [Caveats](docs/Caveats.md) - Flipper beware! (see what I did there)
138
- * [Docker-Compose](docs/DockerCompose.md) - Using docker-compose in contributing
139
-
140
87
  ## Contributing
141
88
 
142
89
  1. Fork it
143
90
  2. Create your feature branch (`git checkout -b my-new-feature`)
144
- 3. Run the tests (`bundle exec rake`)
91
+ 3. Run the tests (`bundle exec rake`). Check out [Docker-Compose](docs/DockerCompose.md) if you need help getting all the adapters running.
145
92
  4. Commit your changes (`git commit -am 'Added some feature'`)
146
93
  5. Push to the branch (`git push origin my-new-feature`)
147
94
  6. Create new Pull Request
@@ -158,6 +105,7 @@ A few miscellaneous docs with more info for the hungry.
158
105
  |---|---|---|
159
106
  | ![@jnunemaker](https://avatars3.githubusercontent.com/u/235?s=64) | [@jnunemaker](https://github.com/jnunemaker) | most things |
160
107
  | ![@bkeepers](https://avatars3.githubusercontent.com/u/173?s=64) | [@bkeepers](https://github.com/bkeepers) | most things |
108
+ | ![@dpep](https://avatars3.githubusercontent.com/u/918804?s=64) | [@dpep](https://github.com/dpep) | tbd |
161
109
  | ![@alexwheeler](https://avatars3.githubusercontent.com/u/3260042?s=64) | [@alexwheeler](https://github.com/alexwheeler) | api |
162
110
  | ![@thetimbanks](https://avatars1.githubusercontent.com/u/471801?s=64) | [@thetimbanks](https://github.com/thetimbanks) | ui |
163
111
  | ![@lazebny](https://avatars1.githubusercontent.com/u/6276766?s=64) | [@lazebny](https://github.com/lazebny) | docker |
data/docs/README.md ADDED
@@ -0,0 +1 @@
1
+ See [flippercloud.io](https://flippercloud.io/docs) for extensive docs.
Binary file
@@ -34,33 +34,27 @@ module Flipper
34
34
  end
35
35
 
36
36
  def add(feature)
37
- result = @remote.add(feature)
38
- @local.add(feature)
39
- result
37
+ @remote.add(feature).tap { @local.add(feature) }
40
38
  end
41
39
 
42
40
  def remove(feature)
43
- result = @remote.remove(feature)
44
- @local.remove(feature)
45
- result
41
+ @remote.remove(feature).tap { @local.remove(feature) }
46
42
  end
47
43
 
48
44
  def clear(feature)
49
- result = @remote.clear(feature)
50
- @local.clear(feature)
51
- result
45
+ @remote.clear(feature).tap { @local.clear(feature) }
52
46
  end
53
47
 
54
48
  def enable(feature, gate, thing)
55
- result = @remote.enable(feature, gate, thing)
56
- @local.enable(feature, gate, thing)
57
- result
49
+ @remote.enable(feature, gate, thing).tap do
50
+ @local.enable(feature, gate, thing)
51
+ end
58
52
  end
59
53
 
60
54
  def disable(feature, gate, thing)
61
- result = @remote.disable(feature, gate, thing)
62
- @local.disable(feature, gate, thing)
63
- result
55
+ @remote.disable(feature, gate, thing).tap do
56
+ @local.disable(feature, gate, thing)
57
+ end
64
58
  end
65
59
  end
66
60
  end
@@ -0,0 +1,83 @@
1
+ module Flipper
2
+ module Adapters
3
+ class Failover
4
+ include ::Flipper::Adapter
5
+
6
+ # Public: The name of the adapter.
7
+ attr_reader :name
8
+
9
+ # Public: Build a new failover instance.
10
+ #
11
+ # primary - The primary flipper adapter.
12
+ # secondary - The secondary flipper adapter which services reads when
13
+ # the primary adapter is unavailable.
14
+ # options - Hash of options:
15
+ # :dual_write - Boolean, whether to update secondary when
16
+ # primary is updated
17
+ # :errors - Array of exception types for which to failover
18
+
19
+ def initialize(primary, secondary, options = {})
20
+ @name = :failover
21
+ @primary = primary
22
+ @secondary = secondary
23
+
24
+ @dual_write = options.fetch(:dual_write, false)
25
+ @errors = options.fetch(:errors, [ StandardError ])
26
+ end
27
+
28
+ def features
29
+ @primary.features
30
+ rescue *@errors
31
+ @secondary.features
32
+ end
33
+
34
+ def get(feature)
35
+ @primary.get(feature)
36
+ rescue *@errors
37
+ @secondary.get(feature)
38
+ end
39
+
40
+ def get_multi(features)
41
+ @primary.get_multi(features)
42
+ rescue *@errors
43
+ @secondary.get_multi(features)
44
+ end
45
+
46
+ def get_all
47
+ @primary.get_all
48
+ rescue *@errors
49
+ @secondary.get_all
50
+ end
51
+
52
+ def add(feature)
53
+ @primary.add(feature).tap do
54
+ @secondary.add(feature) if @dual_write
55
+ end
56
+ end
57
+
58
+ def remove(feature)
59
+ @primary.remove(feature).tap do
60
+ @secondary.remove(feature) if @dual_write
61
+ end
62
+ end
63
+
64
+ def clear(feature)
65
+ @primary.clear(feature).tap do
66
+ @secondary.clear(feature) if @dual_write
67
+ end
68
+ end
69
+
70
+ def enable(feature, gate, thing)
71
+ @primary.enable(feature, gate, thing).tap do
72
+ @secondary.enable(feature, gate, thing) if @dual_write
73
+ end
74
+ end
75
+
76
+ def disable(feature, gate, thing)
77
+ @primary.disable(feature, gate, thing).tap do
78
+ @secondary.disable(feature, gate, thing) if @dual_write
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -70,9 +70,19 @@ module Flipper
70
70
  end
71
71
 
72
72
  def build_request(http_method, uri, headers, options)
73
+ request_headers = {
74
+ "Client-Language" => "ruby",
75
+ "Client-Language-Version" => "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})",
76
+ "Client-Platform" => RUBY_PLATFORM,
77
+ "Client-Engine" => defined?(RUBY_ENGINE) ? RUBY_ENGINE : "",
78
+ "Client-Pid" => Process.pid.to_s,
79
+ "Client-Thread" => Thread.current.object_id.to_s,
80
+ "Client-Hostname" => Socket.gethostname,
81
+ }.merge(headers)
82
+
73
83
  body = options[:body]
74
84
  request = http_method.new(uri.request_uri)
75
- request.initialize_http_header(headers) if headers
85
+ request.initialize_http_header(request_headers)
76
86
  request.body = body if body
77
87
 
78
88
  if @basic_auth_username && @basic_auth_password
@@ -1,3 +1,5 @@
1
+ require "json"
2
+
1
3
  module Flipper
2
4
  module Adapters
3
5
  class Http
@@ -6,7 +8,23 @@ module Flipper
6
8
 
7
9
  def initialize(response)
8
10
  @response = response
9
- super("Failed with status: #{response.code}")
11
+ message = "Failed with status: #{response.code}"
12
+
13
+ begin
14
+ data = JSON.parse(response.body)
15
+
16
+ if error_message = data["message"]
17
+ message << "\n\n#{data["message"]}"
18
+ end
19
+
20
+ if more_info = data["more_info"]
21
+ message << "\n#{data["more_info"]}"
22
+ end
23
+ rescue => exception
24
+ # welp we tried
25
+ end
26
+
27
+ super(message)
10
28
  end
11
29
  end
12
30
  end
@@ -45,24 +45,20 @@ module Flipper
45
45
 
46
46
  # Public
47
47
  def add(feature)
48
- result = @adapter.add(feature)
49
- expire_features_set
50
- result
48
+ @adapter.add(feature).tap { expire_features_set }
51
49
  end
52
50
 
53
51
  # Public
54
52
  def remove(feature)
55
- result = @adapter.remove(feature)
56
- expire_features_set
57
- expire_feature(feature)
58
- result
53
+ @adapter.remove(feature).tap do
54
+ expire_features_set
55
+ expire_feature(feature)
56
+ end
59
57
  end
60
58
 
61
59
  # Public
62
60
  def clear(feature)
63
- result = @adapter.clear(feature)
64
- expire_feature(feature)
65
- result
61
+ @adapter.clear(feature).tap { expire_feature(feature) }
66
62
  end
67
63
 
68
64
  # Public
@@ -124,16 +120,12 @@ module Flipper
124
120
 
125
121
  # Public
126
122
  def enable(feature, gate, thing)
127
- result = @adapter.enable(feature, gate, thing)
128
- expire_feature(feature)
129
- result
123
+ @adapter.enable(feature, gate, thing).tap { expire_feature(feature) }
130
124
  end
131
125
 
132
126
  # Public
133
127
  def disable(feature, gate, thing)
134
- result = @adapter.disable(feature, gate, thing)
135
- expire_feature(feature)
136
- result
128
+ @adapter.disable(feature, gate, thing).tap { expire_feature(feature) }
137
129
  end
138
130
 
139
131
  # Internal: Turns local caching on/off.
@@ -17,14 +17,11 @@ module Flipper
17
17
  # Public: The path to where the file is stored.
18
18
  attr_reader :path
19
19
 
20
- # Public: PStore's thread_safe option.
21
- attr_reader :thread_safe
22
-
23
20
  # Public
24
- def initialize(path = 'flipper.pstore', thread_safe = false)
21
+ def initialize(path = 'flipper.pstore', thread_safe = true)
22
+ @name = :pstore
25
23
  @path = path
26
24
  @store = ::PStore.new(path, thread_safe)
27
- @name = :pstore
28
25
  end
29
26
 
30
27
  # Public: The set of known features.
@@ -7,11 +7,6 @@ module Flipper
7
7
  # Private: Number of seconds between syncs (default: 10).
8
8
  DEFAULT_INTERVAL = 10
9
9
 
10
- # Private
11
- def self.now
12
- Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
13
- end
14
-
15
10
  # Public: The Float or Integer number of seconds between invocations of
16
11
  # the wrapped synchronizer.
17
12
  attr_reader :interval
@@ -46,7 +41,7 @@ module Flipper
46
41
  end
47
42
 
48
43
  def now
49
- self.class.now
44
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
50
45
  end
51
46
  end
52
47
  end
@@ -58,33 +58,27 @@ module Flipper
58
58
  end
59
59
 
60
60
  def add(feature)
61
- result = @remote.add(feature)
62
- @local.add(feature)
63
- result
61
+ @remote.add(feature).tap { @local.add(feature) }
64
62
  end
65
63
 
66
64
  def remove(feature)
67
- result = @remote.remove(feature)
68
- @local.remove(feature)
69
- result
65
+ @remote.remove(feature).tap { @local.remove(feature) }
70
66
  end
71
67
 
72
68
  def clear(feature)
73
- result = @remote.clear(feature)
74
- @local.clear(feature)
75
- result
69
+ @remote.clear(feature).tap { @local.clear(feature) }
76
70
  end
77
71
 
78
72
  def enable(feature, gate, thing)
79
- result = @remote.enable(feature, gate, thing)
80
- @local.enable(feature, gate, thing)
81
- result
73
+ @remote.enable(feature, gate, thing).tap do
74
+ @local.enable(feature, gate, thing)
75
+ end
82
76
  end
83
77
 
84
78
  def disable(feature, gate, thing)
85
- result = @remote.disable(feature, gate, thing)
86
- @local.disable(feature, gate, thing)
87
- result
79
+ @remote.disable(feature, gate, thing).tap do
80
+ @local.disable(feature, gate, thing)
81
+ end
88
82
  end
89
83
 
90
84
  private
@@ -17,9 +17,13 @@ module Flipper
17
17
  # block rather than the one passed to #instrument.
18
18
  payload = payload.dup
19
19
 
20
- result = (yield payload if block_given?)
20
+ result = yield payload if block_given?
21
+ rescue Exception => e
22
+ payload[:exception] = [e.class.name, e.message]
23
+ payload[:exception_object] = e
24
+ raise e
25
+ ensure
21
26
  @events << Event.new(name, payload, result)
22
- result
23
27
  end
24
28
 
25
29
  def events_by_name(name)
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.22.2'.freeze
2
+ VERSION = '0.23.0'.freeze
3
3
  end
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Actor do
4
2
  it 'initializes with and knows flipper_id' do
5
3
  actor = described_class.new("User;235")
@@ -1,5 +1,3 @@
1
- require 'helper'
2
-
3
1
  RSpec.describe Flipper::Adapter do
4
2
  let(:source_flipper) { build_flipper }
5
3
  let(:destination_flipper) { build_flipper }
@@ -1,7 +1,5 @@
1
- require 'helper'
2
1
  require 'flipper/adapters/dual_write'
3
2
  require 'flipper/adapters/operation_logger'
4
- require 'flipper/spec/shared_adapter_specs'
5
3
  require 'active_support/notifications'
6
4
 
7
5
  RSpec.describe Flipper::Adapters::DualWrite do