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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +6 -1
- data/.github/workflows/examples.yml +1 -0
- data/.rspec +1 -0
- data/Changelog.md +18 -2
- data/Gemfile +2 -2
- data/README.md +15 -67
- data/docs/README.md +1 -0
- data/docs/images/banner.jpg +0 -0
- data/lib/flipper/adapters/dual_write.rb +9 -15
- data/lib/flipper/adapters/failover.rb +83 -0
- data/lib/flipper/adapters/http/client.rb +11 -1
- data/lib/flipper/adapters/http/error.rb +19 -1
- data/lib/flipper/adapters/memoizable.rb +8 -16
- data/lib/flipper/adapters/pstore.rb +2 -5
- data/lib/flipper/adapters/sync/interval_synchronizer.rb +1 -6
- data/lib/flipper/adapters/sync.rb +9 -15
- data/lib/flipper/instrumenters/memory.rb +6 -2
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/actor_spec.rb +0 -2
- data/spec/flipper/adapter_spec.rb +0 -2
- data/spec/flipper/adapters/dual_write_spec.rb +0 -2
- data/spec/flipper/adapters/failover_spec.rb +129 -0
- data/spec/flipper/adapters/http_spec.rb +39 -3
- data/spec/flipper/adapters/instrumented_spec.rb +0 -2
- data/spec/flipper/adapters/memoizable_spec.rb +0 -2
- data/spec/flipper/adapters/memory_spec.rb +0 -3
- data/spec/flipper/adapters/operation_logger_spec.rb +0 -2
- data/spec/flipper/adapters/pstore_spec.rb +0 -2
- data/spec/flipper/adapters/read_only_spec.rb +0 -1
- data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +0 -1
- data/spec/flipper/adapters/sync/interval_synchronizer_spec.rb +4 -5
- data/spec/flipper/adapters/sync/synchronizer_spec.rb +0 -1
- data/spec/flipper/adapters/sync_spec.rb +0 -2
- data/spec/flipper/configuration_spec.rb +0 -1
- data/spec/flipper/dsl_spec.rb +0 -1
- data/spec/flipper/feature_check_context_spec.rb +0 -2
- data/spec/flipper/feature_spec.rb +0 -1
- data/spec/flipper/gate_spec.rb +0 -2
- data/spec/flipper/gate_values_spec.rb +0 -1
- data/spec/flipper/gates/actor_spec.rb +0 -2
- data/spec/flipper/gates/boolean_spec.rb +0 -2
- data/spec/flipper/gates/group_spec.rb +0 -2
- data/spec/flipper/gates/percentage_of_actors_spec.rb +0 -2
- data/spec/flipper/gates/percentage_of_time_spec.rb +0 -2
- data/spec/flipper/identifier_spec.rb +0 -1
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +0 -1
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +0 -1
- data/spec/flipper/instrumenters/memory_spec.rb +18 -1
- data/spec/flipper/instrumenters/noop_spec.rb +14 -8
- data/spec/flipper/middleware/memoizer_spec.rb +0 -2
- data/spec/flipper/middleware/setup_env_spec.rb +0 -2
- data/spec/flipper/railtie_spec.rb +17 -19
- data/spec/flipper/registry_spec.rb +0 -1
- data/spec/flipper/typecast_spec.rb +0 -1
- data/spec/flipper/types/actor_spec.rb +0 -1
- data/spec/flipper/types/boolean_spec.rb +0 -1
- data/spec/flipper/types/group_spec.rb +0 -1
- data/spec/flipper/types/percentage_of_actors_spec.rb +0 -1
- data/spec/flipper/types/percentage_of_time_spec.rb +0 -1
- data/spec/flipper/types/percentage_spec.rb +0 -1
- data/spec/flipper_integration_spec.rb +0 -1
- data/spec/flipper_spec.rb +0 -1
- data/spec/{helper.rb → spec_helper.rb} +2 -1
- data/spec/support/spec_helpers.rb +2 -6
- metadata +10 -13
- data/docs/Adapters.md +0 -124
- data/docs/Caveats.md +0 -4
- data/docs/Gates.md +0 -167
- data/docs/Instrumentation.md +0 -27
- data/docs/Optimization.md +0 -137
- data/docs/api/README.md +0 -884
- data/docs/http/README.md +0 -36
- data/docs/read-only/README.md +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c7754b40752e0c255308fedfb6ef7784e7e9b3cf4ba0035a289a02074e61e4e7
|
|
4
|
+
data.tar.gz: 7e0add2ac95c2dc929a97fef218ece9fbc904c911ffe6f4ac1d3ccbc36befab9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e5b7b82f89f1cdbb93f0a07d6909aea686214e9ce6a7c1daf4661f900da5e3dfe3176ed89ffe1bb63b8317788bce1a662ad27b2e88b01bebb77856213be7f4d
|
|
7
|
+
data.tar.gz: e8d25c0ed393a34f4f7ec93b2d2ec8707f009ba35e83ef606d4850c7031bb7e923af83c2472fd2d6d00004d6561f410156021b7892dab20883dd0c6fe2efcb15
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -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
|
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/
|
|
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'] || '
|
|
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 '
|
|
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
|
[](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](
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-

|
|
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
|
-
|
|
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://github.com/jnunemaker) | most things |
|
|
160
107
|
|  | [@bkeepers](https://github.com/bkeepers) | most things |
|
|
108
|
+
|  | [@dpep](https://github.com/dpep) | tbd |
|
|
161
109
|
|  | [@alexwheeler](https://github.com/alexwheeler) | api |
|
|
162
110
|
|  | [@thetimbanks](https://github.com/thetimbanks) | ui |
|
|
163
111
|
|  | [@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.
|
data/docs/images/banner.jpg
CHANGED
|
Binary file
|
|
@@ -34,33 +34,27 @@ module Flipper
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def add(feature)
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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 =
|
|
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)
|
data/lib/flipper/version.rb
CHANGED
data/spec/flipper/actor_spec.rb
CHANGED