flipper 0.26.0 → 1.1.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/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +19 -13
- data/.github/workflows/examples.yml +32 -15
- data/Changelog.md +294 -154
- data/Gemfile +15 -10
- data/README.md +13 -11
- data/benchmark/enabled_ips.rb +10 -0
- data/benchmark/enabled_multiple_actors_ips.rb +20 -0
- data/benchmark/enabled_profile.rb +20 -0
- data/benchmark/instrumentation_ips.rb +21 -0
- data/benchmark/typecast_ips.rb +27 -0
- data/docs/images/flipper_cloud.png +0 -0
- data/examples/api/basic.ru +3 -4
- data/examples/api/custom_memoized.ru +3 -4
- data/examples/api/memoized.ru +3 -4
- data/examples/cloud/app.ru +12 -0
- data/examples/cloud/backoff_policy.rb +13 -0
- data/examples/cloud/basic.rb +22 -0
- data/examples/cloud/cloud_setup.rb +20 -0
- data/examples/cloud/forked.rb +36 -0
- data/examples/cloud/import.rb +17 -0
- data/examples/cloud/threaded.rb +33 -0
- data/examples/dsl.rb +1 -15
- data/examples/enabled_for_actor.rb +4 -2
- data/examples/expressions.rb +213 -0
- data/examples/mirroring.rb +59 -0
- data/examples/strict.rb +18 -0
- data/flipper-cloud.gemspec +19 -0
- data/flipper.gemspec +3 -5
- data/lib/flipper/actor.rb +6 -3
- data/lib/flipper/adapter.rb +33 -7
- data/lib/flipper/adapter_builder.rb +44 -0
- data/lib/flipper/adapters/dual_write.rb +1 -3
- data/lib/flipper/adapters/failover.rb +0 -4
- data/lib/flipper/adapters/failsafe.rb +0 -4
- data/lib/flipper/adapters/http/client.rb +26 -7
- data/lib/flipper/adapters/http/error.rb +1 -1
- data/lib/flipper/adapters/http.rb +29 -16
- data/lib/flipper/adapters/instrumented.rb +25 -6
- data/lib/flipper/adapters/memoizable.rb +33 -21
- data/lib/flipper/adapters/memory.rb +81 -46
- data/lib/flipper/adapters/operation_logger.rb +16 -7
- data/lib/flipper/adapters/poll/poller.rb +2 -125
- data/lib/flipper/adapters/poll.rb +5 -3
- data/lib/flipper/adapters/pstore.rb +17 -11
- data/lib/flipper/adapters/read_only.rb +4 -4
- data/lib/flipper/adapters/strict.rb +47 -0
- data/lib/flipper/adapters/sync/feature_synchronizer.rb +10 -1
- data/lib/flipper/adapters/sync.rb +0 -4
- data/lib/flipper/cloud/configuration.rb +258 -0
- data/lib/flipper/cloud/dsl.rb +27 -0
- data/lib/flipper/cloud/message_verifier.rb +95 -0
- data/lib/flipper/cloud/middleware.rb +63 -0
- data/lib/flipper/cloud/routes.rb +14 -0
- data/lib/flipper/cloud/telemetry/backoff_policy.rb +93 -0
- data/lib/flipper/cloud/telemetry/instrumenter.rb +26 -0
- data/lib/flipper/cloud/telemetry/metric.rb +39 -0
- data/lib/flipper/cloud/telemetry/metric_storage.rb +30 -0
- data/lib/flipper/cloud/telemetry/submitter.rb +98 -0
- data/lib/flipper/cloud/telemetry.rb +183 -0
- data/lib/flipper/cloud.rb +53 -0
- data/lib/flipper/configuration.rb +25 -4
- data/lib/flipper/dsl.rb +46 -45
- data/lib/flipper/engine.rb +88 -0
- data/lib/flipper/errors.rb +3 -3
- data/lib/flipper/export.rb +26 -0
- data/lib/flipper/exporter.rb +17 -0
- data/lib/flipper/exporters/json/export.rb +32 -0
- data/lib/flipper/exporters/json/v1.rb +33 -0
- data/lib/flipper/expression/builder.rb +73 -0
- data/lib/flipper/expression/constant.rb +25 -0
- data/lib/flipper/expression.rb +71 -0
- data/lib/flipper/expressions/all.rb +11 -0
- data/lib/flipper/expressions/any.rb +9 -0
- data/lib/flipper/expressions/boolean.rb +9 -0
- data/lib/flipper/expressions/comparable.rb +13 -0
- data/lib/flipper/expressions/duration.rb +28 -0
- data/lib/flipper/expressions/equal.rb +9 -0
- data/lib/flipper/expressions/greater_than.rb +9 -0
- data/lib/flipper/expressions/greater_than_or_equal_to.rb +9 -0
- data/lib/flipper/expressions/less_than.rb +9 -0
- data/lib/flipper/expressions/less_than_or_equal_to.rb +9 -0
- data/lib/flipper/expressions/not_equal.rb +9 -0
- data/lib/flipper/expressions/now.rb +9 -0
- data/lib/flipper/expressions/number.rb +9 -0
- data/lib/flipper/expressions/percentage.rb +9 -0
- data/lib/flipper/expressions/percentage_of_actors.rb +12 -0
- data/lib/flipper/expressions/property.rb +9 -0
- data/lib/flipper/expressions/random.rb +9 -0
- data/lib/flipper/expressions/string.rb +9 -0
- data/lib/flipper/expressions/time.rb +9 -0
- data/lib/flipper/feature.rb +87 -26
- data/lib/flipper/feature_check_context.rb +10 -6
- data/lib/flipper/gate.rb +13 -11
- data/lib/flipper/gate_values.rb +5 -18
- data/lib/flipper/gates/actor.rb +10 -17
- data/lib/flipper/gates/boolean.rb +1 -1
- data/lib/flipper/gates/expression.rb +75 -0
- data/lib/flipper/gates/group.rb +5 -7
- data/lib/flipper/gates/percentage_of_actors.rb +10 -13
- data/lib/flipper/gates/percentage_of_time.rb +1 -2
- data/lib/flipper/identifier.rb +2 -2
- data/lib/flipper/instrumentation/log_subscriber.rb +24 -5
- data/lib/flipper/instrumentation/statsd_subscriber.rb +2 -4
- data/lib/flipper/instrumentation/subscriber.rb +8 -1
- data/lib/flipper/metadata.rb +5 -1
- data/lib/flipper/middleware/memoizer.rb +30 -14
- data/lib/flipper/poller.rb +117 -0
- data/lib/flipper/serializers/gzip.rb +24 -0
- data/lib/flipper/serializers/json.rb +19 -0
- data/lib/flipper/spec/shared_adapter_specs.rb +95 -54
- data/lib/flipper/test/shared_adapter_test.rb +91 -48
- data/lib/flipper/typecast.rb +56 -15
- data/lib/flipper/types/actor.rb +13 -13
- data/lib/flipper/types/group.rb +4 -4
- data/lib/flipper/types/percentage.rb +1 -1
- data/lib/flipper/version.rb +1 -1
- data/lib/flipper.rb +47 -10
- data/spec/fixtures/flipper_pstore_1679087600.json +46 -0
- data/spec/flipper/adapter_builder_spec.rb +73 -0
- data/spec/flipper/adapter_spec.rb +30 -2
- data/spec/flipper/adapters/dual_write_spec.rb +2 -2
- data/spec/flipper/adapters/http_spec.rb +64 -8
- data/spec/flipper/adapters/instrumented_spec.rb +29 -11
- data/spec/flipper/adapters/memoizable_spec.rb +51 -31
- data/spec/flipper/adapters/memory_spec.rb +14 -3
- data/spec/flipper/adapters/operation_logger_spec.rb +31 -12
- data/spec/flipper/adapters/read_only_spec.rb +32 -17
- data/spec/flipper/adapters/strict_spec.rb +62 -0
- data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +27 -0
- data/spec/flipper/cloud/configuration_spec.rb +252 -0
- data/spec/flipper/cloud/dsl_spec.rb +82 -0
- data/spec/flipper/cloud/message_verifier_spec.rb +104 -0
- data/spec/flipper/cloud/middleware_spec.rb +289 -0
- data/spec/flipper/cloud/telemetry/backoff_policy_spec.rb +108 -0
- data/spec/flipper/cloud/telemetry/metric_spec.rb +87 -0
- data/spec/flipper/cloud/telemetry/metric_storage_spec.rb +58 -0
- data/spec/flipper/cloud/telemetry/submitter_spec.rb +145 -0
- data/spec/flipper/cloud/telemetry_spec.rb +156 -0
- data/spec/flipper/cloud_spec.rb +180 -0
- data/spec/flipper/configuration_spec.rb +17 -0
- data/spec/flipper/dsl_spec.rb +54 -73
- data/spec/flipper/engine_spec.rb +291 -0
- data/spec/flipper/export_spec.rb +13 -0
- data/spec/flipper/exporter_spec.rb +16 -0
- data/spec/flipper/exporters/json/export_spec.rb +60 -0
- data/spec/flipper/exporters/json/v1_spec.rb +33 -0
- data/spec/flipper/expression/builder_spec.rb +248 -0
- data/spec/flipper/expression_spec.rb +188 -0
- data/spec/flipper/expressions/all_spec.rb +15 -0
- data/spec/flipper/expressions/any_spec.rb +15 -0
- data/spec/flipper/expressions/boolean_spec.rb +15 -0
- data/spec/flipper/expressions/duration_spec.rb +43 -0
- data/spec/flipper/expressions/equal_spec.rb +24 -0
- data/spec/flipper/expressions/greater_than_or_equal_to_spec.rb +28 -0
- data/spec/flipper/expressions/greater_than_spec.rb +28 -0
- data/spec/flipper/expressions/less_than_or_equal_to_spec.rb +28 -0
- data/spec/flipper/expressions/less_than_spec.rb +32 -0
- data/spec/flipper/expressions/not_equal_spec.rb +15 -0
- data/spec/flipper/expressions/now_spec.rb +11 -0
- data/spec/flipper/expressions/number_spec.rb +21 -0
- data/spec/flipper/expressions/percentage_of_actors_spec.rb +20 -0
- data/spec/flipper/expressions/percentage_spec.rb +15 -0
- data/spec/flipper/expressions/property_spec.rb +13 -0
- data/spec/flipper/expressions/random_spec.rb +9 -0
- data/spec/flipper/expressions/string_spec.rb +11 -0
- data/spec/flipper/expressions/time_spec.rb +13 -0
- data/spec/flipper/feature_check_context_spec.rb +17 -17
- data/spec/flipper/feature_spec.rb +436 -33
- data/spec/flipper/gate_values_spec.rb +2 -33
- data/spec/flipper/gates/boolean_spec.rb +1 -1
- data/spec/flipper/gates/expression_spec.rb +108 -0
- data/spec/flipper/gates/group_spec.rb +2 -3
- data/spec/flipper/gates/percentage_of_actors_spec.rb +61 -5
- data/spec/flipper/gates/percentage_of_time_spec.rb +2 -2
- data/spec/flipper/identifier_spec.rb +4 -5
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +15 -5
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +25 -1
- data/spec/flipper/middleware/memoizer_spec.rb +67 -0
- data/spec/flipper/poller_spec.rb +47 -0
- data/spec/flipper/serializers/gzip_spec.rb +13 -0
- data/spec/flipper/serializers/json_spec.rb +13 -0
- data/spec/flipper/typecast_spec.rb +121 -6
- data/spec/flipper/types/actor_spec.rb +63 -46
- data/spec/flipper/types/group_spec.rb +2 -2
- data/spec/flipper_integration_spec.rb +168 -58
- data/spec/flipper_spec.rb +92 -28
- data/spec/spec_helper.rb +6 -13
- data/spec/support/actor_names.yml +1 -0
- data/spec/support/climate_control.rb +7 -0
- data/spec/support/fake_backoff_policy.rb +15 -0
- data/spec/support/skippable.rb +18 -0
- data/spec/support/spec_helpers.rb +11 -3
- metadata +166 -13
- data/.github/workflows/release.yml +0 -44
- data/.tool-versions +0 -1
- data/lib/flipper/railtie.rb +0 -47
- data/spec/flipper/railtie_spec.rb +0 -109
data/Gemfile
CHANGED
@@ -7,23 +7,28 @@ Dir['flipper-*.gemspec'].each do |gemspec|
|
|
7
7
|
end
|
8
8
|
|
9
9
|
gem 'debug'
|
10
|
-
gem 'rake'
|
11
|
-
gem 'shotgun', '~> 0.9'
|
10
|
+
gem 'rake'
|
12
11
|
gem 'statsd-ruby', '~> 1.2.1'
|
13
12
|
gem 'rspec', '~> 3.0'
|
14
|
-
gem 'rack-test'
|
13
|
+
gem 'rack-test'
|
14
|
+
gem 'rackup'
|
15
15
|
gem 'sqlite3', "~> #{ENV['SQLITE3_VERSION'] || '1.4.1'}"
|
16
|
-
gem 'rails', "~> #{ENV['RAILS_VERSION'] || '7.0.
|
17
|
-
gem 'minitest', '~> 5.
|
16
|
+
gem 'rails', "~> #{ENV['RAILS_VERSION'] || '7.0.4'}"
|
17
|
+
gem 'minitest', '~> 5.18'
|
18
18
|
gem 'minitest-documentation'
|
19
|
-
gem 'webmock'
|
19
|
+
gem 'webmock'
|
20
20
|
gem 'ice_age'
|
21
21
|
gem 'redis-namespace'
|
22
22
|
gem 'webrick'
|
23
|
+
gem 'stackprof'
|
24
|
+
gem 'benchmark-ips'
|
25
|
+
gem 'stackprof-webnav'
|
26
|
+
gem 'flamegraph'
|
27
|
+
gem 'climate_control'
|
23
28
|
|
24
29
|
group(:guard) do
|
25
|
-
gem 'guard'
|
26
|
-
gem 'guard-rspec'
|
27
|
-
gem 'guard-bundler'
|
28
|
-
gem 'rb-fsevent'
|
30
|
+
gem 'guard'
|
31
|
+
gem 'guard-rspec'
|
32
|
+
gem 'guard-bundler'
|
33
|
+
gem 'rb-fsevent'
|
29
34
|
end
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
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)
|
3
|
+
[Website](https://flippercloud.io?utm_source=oss&utm_medium=readme&utm_campaign=website_link) | [Documentation](https://flippercloud.io/docs?utm_source=oss&utm_medium=readme&utm_campaign=docs_link) | [Examples](examples) | [Twitter](https://twitter.com/flipper_cloud) | [Ruby.social](https://ruby.social/@flipper)
|
4
4
|
|
5
5
|
# Flipper
|
6
6
|
|
@@ -35,7 +35,7 @@ Or install it yourself with:
|
|
35
35
|
|
36
36
|
## Subscribe & Ship
|
37
37
|
|
38
|
-
[💌 Subscribe](https://
|
38
|
+
[💌 Subscribe](https://blog.flippercloud.io/#/portal/signup) - we'll send you short and sweet emails when we release new versions ([examples](https://blog.flippercloud.io/tag/releases/)).
|
39
39
|
|
40
40
|
## Getting Started
|
41
41
|
|
@@ -43,7 +43,7 @@ Use `Flipper#enabled?` in your app to check if a feature is enabled.
|
|
43
43
|
|
44
44
|
```ruby
|
45
45
|
# check if search is enabled
|
46
|
-
if Flipper.enabled?
|
46
|
+
if Flipper.enabled?(:search, current_user)
|
47
47
|
puts 'Search away!'
|
48
48
|
else
|
49
49
|
puts 'No search for you!'
|
@@ -66,24 +66,26 @@ Flipper.enable_group :search, :admin
|
|
66
66
|
Flipper.enable_percentage_of_actors :search, 2
|
67
67
|
```
|
68
68
|
|
69
|
-
Read more about [getting started with Flipper](https://flippercloud.io/docs) and [enabling features](https://flippercloud.io/docs/features).
|
69
|
+
Read more about [getting started with Flipper](https://flippercloud.io/docs?utm_source=oss&utm_medium=readme&utm_campaign=getting_started) and [enabling features](https://flippercloud.io/docs/features?utm_source=oss&utm_medium=readme&utm_campaign=enabling_features).
|
70
70
|
|
71
71
|
## Flipper Cloud
|
72
72
|
|
73
|
-
Like Flipper and want more? Check out [Flipper Cloud](https://www.flippercloud.io), which comes with:
|
73
|
+
Like Flipper and want more? Check out [Flipper Cloud](https://www.flippercloud.io?utm_source=oss&utm_medium=readme&utm_campaign=check_out), which comes with:
|
74
74
|
|
75
|
-
* **
|
76
|
-
* **
|
77
|
-
* **
|
78
|
-
* **personal environments** — no more rake scripts or manual enable/disable to get your laptop to look like production. Every developer gets a personal environment that inherits from production that they can override as they please ([read more](https://www.johnnunemaker.com/flipper-cloud-environments/)).
|
79
|
-
* **no maintenance** — we'll keep the lights on for you. We also have handy webhooks for keeping your app in sync with Cloud, so **our availability won't affect yours**. All your feature flag reads are local to your app.
|
75
|
+
* **multiple environments** — production, staging, per continent, whatever you need. Every environment inherits from production by default and every project comes with a [project overview page](https://blog.flippercloud.io/project-overview/) that shows each feature and its status in each environment.
|
76
|
+
* **personal environments** — everyone on your team gets a personal environment (that inherits from production) which they can modify however they want without stepping on anyone else's toes.
|
77
|
+
* **permissions** — grant access to everyone in your organization or lockdown each project to particular people. You can even limit access to a particular environment (like production) to specific people.
|
80
78
|
* **audit history** — every feature change and who made it.
|
81
79
|
* **rollbacks** — enable or disable a feature accidentally? No problem. You can roll back to any point in the audit history with a single click.
|
80
|
+
* **maintenance** — we'll keep the lights on for you. We also have handy webhooks and background polling for keeping your app in sync with Cloud, so **our availability won't affect yours**. All your feature flag reads are local to your app.
|
81
|
+
* **everything in one place** — no need to bounce around from different application UIs or IRB consoles.
|
82
82
|
|
83
|
-
[](https://www.flippercloud.io)
|
83
|
+
[](https://www.flippercloud.io?utm_source=oss&utm_medium=readme&utm_campaign=screenshot)
|
84
84
|
|
85
85
|
Cloud is super simple to integrate with Rails ([demo app](https://github.com/fewerandfaster/flipper-rails-demo)), Sinatra or any other framework.
|
86
86
|
|
87
|
+
We also have a [free plan](https://www.flippercloud.io?utm_source=oss&utm_medium=readme&utm_campaign=free_plan) that you can use forever.
|
88
|
+
|
87
89
|
## Contributing
|
88
90
|
|
89
91
|
1. Fork it
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'flipper'
|
3
|
+
require 'benchmark/ips'
|
4
|
+
|
5
|
+
actor1 = Flipper::Actor.new("User;1")
|
6
|
+
actor2 = Flipper::Actor.new("User;2")
|
7
|
+
actor3 = Flipper::Actor.new("User;3")
|
8
|
+
actor4 = Flipper::Actor.new("User;4")
|
9
|
+
actor5 = Flipper::Actor.new("User;5")
|
10
|
+
actor6 = Flipper::Actor.new("User;6")
|
11
|
+
actor7 = Flipper::Actor.new("User;7")
|
12
|
+
actor8 = Flipper::Actor.new("User;8")
|
13
|
+
|
14
|
+
actors = [actor1, actor2, actor3, actor4, actor5, actor6, actor7, actor8]
|
15
|
+
|
16
|
+
Benchmark.ips do |x|
|
17
|
+
x.report("with array of actors") { Flipper.enabled?(:foo, actors) }
|
18
|
+
x.report("with multiple enabled? checks") { actors.each { |actor| Flipper.enabled?(:foo, actor) } }
|
19
|
+
x.compare!
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'flipper'
|
3
|
+
require 'stackprof'
|
4
|
+
require 'benchmark/ips'
|
5
|
+
|
6
|
+
flipper = Flipper.new(Flipper::Adapters::Memory.new)
|
7
|
+
feature = flipper.feature(:foo)
|
8
|
+
actor = Flipper::Actor.new("User;1")
|
9
|
+
|
10
|
+
profile = StackProf.run(mode: :wall, interval: 1_000) do
|
11
|
+
2_000_000.times do
|
12
|
+
feature.enabled?(actor)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
result = StackProf::Report.new(profile)
|
17
|
+
puts
|
18
|
+
result.print_text
|
19
|
+
puts "\n\n\n"
|
20
|
+
result.print_method(/Flipper::Feature#enabled?/)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'flipper'
|
3
|
+
require 'active_support/notifications'
|
4
|
+
require 'active_support/isolated_execution_state'
|
5
|
+
require 'benchmark/ips'
|
6
|
+
|
7
|
+
class FlipperSubscriber
|
8
|
+
def call(name, start, finish, id, payload)
|
9
|
+
end
|
10
|
+
|
11
|
+
ActiveSupport::Notifications.subscribe(/flipper/, new)
|
12
|
+
end
|
13
|
+
|
14
|
+
actor = Flipper::Actor.new("User;1")
|
15
|
+
bare = Flipper.new(Flipper::Adapters::Memory.new)
|
16
|
+
instrumented = Flipper.new(Flipper::Adapters::Memory.new, instrumenter: ActiveSupport::Notifications)
|
17
|
+
|
18
|
+
Benchmark.ips do |x|
|
19
|
+
x.report("with instrumentation") { instrumented.enabled?(:foo, actor) }
|
20
|
+
x.report("without instrumentation") { bare.enabled?(:foo, actor) }
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'flipper'
|
3
|
+
require 'benchmark/ips'
|
4
|
+
|
5
|
+
Benchmark.ips do |x|
|
6
|
+
x.report("Typecast.to_boolean true") { Flipper::Typecast.to_boolean(true) }
|
7
|
+
x.report("Typecast.to_boolean 1") { Flipper::Typecast.to_boolean(1) }
|
8
|
+
x.report("Typecast.to_boolean 'true'") { Flipper::Typecast.to_boolean('true'.freeze) }
|
9
|
+
x.report("Typecast.to_boolean '1'") { Flipper::Typecast.to_boolean('1'.freeze) }
|
10
|
+
x.report("Typecast.to_boolean false") { Flipper::Typecast.to_boolean(false) }
|
11
|
+
|
12
|
+
x.report("Typecast.to_integer 1") { Flipper::Typecast.to_integer(1) }
|
13
|
+
x.report("Typecast.to_integer '1'") { Flipper::Typecast.to_integer('1') }
|
14
|
+
|
15
|
+
x.report("Typecast.to_float 1") { Flipper::Typecast.to_float(1) }
|
16
|
+
x.report("Typecast.to_float '1'") { Flipper::Typecast.to_float('1'.freeze) }
|
17
|
+
x.report("Typecast.to_float 1.01") { Flipper::Typecast.to_float(1) }
|
18
|
+
x.report("Typecast.to_float '1.01'") { Flipper::Typecast.to_float('1'.freeze) }
|
19
|
+
|
20
|
+
x.report("Typecast.to_number 1") { Flipper::Typecast.to_number(1) }
|
21
|
+
x.report("Typecast.to_number 1.1") { Flipper::Typecast.to_number(1.1) }
|
22
|
+
x.report("Typecast.to_number '1'") { Flipper::Typecast.to_number('1'.freeze) }
|
23
|
+
x.report("Typecast.to_number '1.1'") { Flipper::Typecast.to_number('1.1'.freeze) }
|
24
|
+
x.report("Typecast.to_number nil") { Flipper::Typecast.to_number(nil) }
|
25
|
+
time = Time.now
|
26
|
+
x.report("Typecast.to_number Time.now") { Flipper::Typecast.to_number(time) }
|
27
|
+
end
|
Binary file
|
data/examples/api/basic.ru
CHANGED
@@ -1,19 +1,18 @@
|
|
1
1
|
#
|
2
2
|
# Usage:
|
3
|
-
# # if you want it to not reload and be really fast
|
4
3
|
# bin/rackup examples/api/basic.ru -p 9999
|
5
4
|
#
|
6
|
-
# # if you want reloading
|
7
|
-
# bin/shotgun examples/api/basic.ru -p 9999
|
8
|
-
#
|
9
5
|
# http://localhost:9999/
|
10
6
|
#
|
11
7
|
|
12
8
|
require 'bundler/setup'
|
9
|
+
require 'rack/reloader'
|
13
10
|
require "flipper/api"
|
14
11
|
require "flipper/adapters/pstore"
|
15
12
|
|
16
13
|
# You can uncomment this to get some default data:
|
17
14
|
# Flipper.enable :logging
|
18
15
|
|
16
|
+
use Rack::Reloader
|
17
|
+
|
19
18
|
run Flipper::Api.app
|
@@ -1,15 +1,12 @@
|
|
1
1
|
#
|
2
2
|
# Usage:
|
3
|
-
# # if you want it to not reload and be really fast
|
4
3
|
# bin/rackup examples/api/custom_memoized.ru -p 9999
|
5
4
|
#
|
6
|
-
# # if you want reloading
|
7
|
-
# bin/shotgun examples/api/custom_memoized.ru -p 9999
|
8
|
-
#
|
9
5
|
# http://localhost:9999/
|
10
6
|
#
|
11
7
|
|
12
8
|
require 'bundler/setup'
|
9
|
+
require 'rack/reloader'
|
13
10
|
require "active_support/notifications"
|
14
11
|
require "flipper/api"
|
15
12
|
require "flipper/adapters/pstore"
|
@@ -31,6 +28,8 @@ ActiveSupport::Notifications.subscribe(/.*/, ->(*args) {
|
|
31
28
|
# You can uncomment this to get some default data:
|
32
29
|
# flipper[:logging].enable_percentage_of_time 5
|
33
30
|
|
31
|
+
use Rack::Reloader
|
32
|
+
|
34
33
|
run Flipper::Api.app(flipper) { |builder|
|
35
34
|
builder.use Flipper::Middleware::SetupEnv, flipper
|
36
35
|
builder.use Flipper::Middleware::Memoizer, preload: true
|
data/examples/api/memoized.ru
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
#
|
2
2
|
# Usage:
|
3
|
-
# # if you want it to not reload and be really fast
|
4
3
|
# bin/rackup examples/api/memoized.ru -p 9999
|
5
4
|
#
|
6
|
-
# # if you want reloading
|
7
|
-
# bin/shotgun examples/api/memoized.ru -p 9999
|
8
|
-
#
|
9
5
|
# http://localhost:9999/
|
10
6
|
#
|
11
7
|
|
12
8
|
require 'bundler/setup'
|
9
|
+
require 'rack/reloader'
|
13
10
|
require "active_support/notifications"
|
14
11
|
require "flipper/api"
|
15
12
|
require "flipper/adapters/pstore"
|
@@ -38,6 +35,8 @@ Flipper.register(:admins) { |actor|
|
|
38
35
|
# You can uncomment this to get some default data:
|
39
36
|
# Flipper.enable :logging
|
40
37
|
|
38
|
+
use Rack::Reloader
|
39
|
+
|
41
40
|
run Flipper::Api.app { |builder|
|
42
41
|
builder.use Flipper::Middleware::Memoizer, preload: true
|
43
42
|
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Usage (from the repo root):
|
2
|
+
# env FLIPPER_CLOUD_TOKEN=<token> FLIPPER_CLOUD_SYNC_SECRET=<secret> bundle exec rackup examples/cloud/app.ru -p 9999
|
3
|
+
# http://localhost:9999/
|
4
|
+
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'flipper/cloud'
|
7
|
+
|
8
|
+
Flipper.configure do |config|
|
9
|
+
config.default { Flipper::Cloud.new }
|
10
|
+
end
|
11
|
+
|
12
|
+
run Flipper::Cloud.app
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Just a simple example that shows how the backoff policy works.
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'flipper/cloud/telemetry/backoff_policy'
|
4
|
+
|
5
|
+
intervals = []
|
6
|
+
policy = Flipper::Cloud::Telemetry::BackoffPolicy.new
|
7
|
+
|
8
|
+
10.times do |n|
|
9
|
+
intervals << policy.next_interval
|
10
|
+
end
|
11
|
+
|
12
|
+
pp intervals.map { |i| i.round(2) }
|
13
|
+
puts "Total: #{intervals.sum.round(2)}ms (#{(intervals.sum/1_000.0).round(2)} sec)"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Usage (from the repo root):
|
2
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/basic.rb
|
3
|
+
|
4
|
+
require_relative "./cloud_setup"
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'flipper/cloud'
|
7
|
+
|
8
|
+
Flipper[:stats].enable
|
9
|
+
|
10
|
+
if Flipper[:stats].enabled?
|
11
|
+
puts 'Enabled!'
|
12
|
+
else
|
13
|
+
puts 'Disabled!'
|
14
|
+
end
|
15
|
+
|
16
|
+
Flipper[:stats].disable
|
17
|
+
|
18
|
+
if Flipper[:stats].enabled?
|
19
|
+
puts 'Enabled!'
|
20
|
+
else
|
21
|
+
puts 'Disabled!'
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
if ENV["FLIPPER_CLOUD_TOKEN"].nil? || ENV["FLIPPER_CLOUD_TOKEN"].empty?
|
2
|
+
warn "FLIPPER_CLOUD_TOKEN missing so skipping cloud example."
|
3
|
+
exit
|
4
|
+
end
|
5
|
+
|
6
|
+
matrix_key = if ENV["CI"]
|
7
|
+
suffix_rails = ENV["RAILS_VERSION"].split(".").take(2).join
|
8
|
+
suffix_ruby = RUBY_VERSION.split(".").take(2).join
|
9
|
+
"FLIPPER_CLOUD_TOKEN_#{suffix_ruby}_#{suffix_rails}"
|
10
|
+
else
|
11
|
+
"FLIPPER_CLOUD_TOKEN"
|
12
|
+
end
|
13
|
+
|
14
|
+
if matrix_token = ENV[matrix_key]
|
15
|
+
puts "Using #{matrix_key} for FLIPPER_CLOUD_TOKEN"
|
16
|
+
ENV["FLIPPER_CLOUD_TOKEN"] = matrix_token
|
17
|
+
else
|
18
|
+
warn "Missing #{matrix_key}. Go create an environment in flipper cloud and set #{matrix_key} to the adapter token for that environment in github actions secrets."
|
19
|
+
exit 1
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Usage (from the repo root):
|
2
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/threaded.rb
|
3
|
+
|
4
|
+
require_relative "./cloud_setup"
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'flipper/cloud'
|
7
|
+
|
8
|
+
puts Process.pid
|
9
|
+
|
10
|
+
# Make a call in the parent process so we can detect forking.
|
11
|
+
Flipper.enabled?(:stats)
|
12
|
+
|
13
|
+
pids = 2.times.map do |n|
|
14
|
+
fork {
|
15
|
+
# Check every second to see if the feature is enabled
|
16
|
+
threads = []
|
17
|
+
2.times do
|
18
|
+
threads << Thread.new do
|
19
|
+
loop do
|
20
|
+
sleep rand
|
21
|
+
|
22
|
+
if Flipper[:stats].enabled?
|
23
|
+
puts "#{Process.pid} #{Time.now.to_i} Enabled!"
|
24
|
+
else
|
25
|
+
puts "#{Process.pid} #{Time.now.to_i} Disabled!"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
threads.map(&:join)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
pids.each do |pid|
|
35
|
+
Process.waitpid pid, 0
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Usage (from the repo root):
|
2
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/import.rb
|
3
|
+
|
4
|
+
require_relative "./cloud_setup"
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'flipper'
|
7
|
+
require 'flipper/cloud'
|
8
|
+
|
9
|
+
Flipper.enable(:test)
|
10
|
+
Flipper.enable(:search)
|
11
|
+
Flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
|
12
|
+
Flipper.enable_percentage_of_time(:logging, 5)
|
13
|
+
|
14
|
+
cloud = Flipper::Cloud.new
|
15
|
+
|
16
|
+
# makes cloud identical to memory flipper
|
17
|
+
cloud.import(Flipper)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Usage (from the repo root):
|
2
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/threaded.rb
|
3
|
+
|
4
|
+
require_relative "./cloud_setup"
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'flipper/cloud'
|
7
|
+
|
8
|
+
puts Process.pid
|
9
|
+
|
10
|
+
Flipper.configure do |config|
|
11
|
+
config.default {
|
12
|
+
Flipper::Cloud.new(
|
13
|
+
local_adapter: config.adapter,
|
14
|
+
debug_output: STDOUT,
|
15
|
+
)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
# You might want to do this at some point to see different results:
|
20
|
+
# Flipper.enable(:search)
|
21
|
+
# Flipper.disable(:stats)
|
22
|
+
|
23
|
+
# Check every second to see if the feature is enabled
|
24
|
+
5.times.map { |i|
|
25
|
+
Thread.new {
|
26
|
+
loop do
|
27
|
+
sleep rand
|
28
|
+
|
29
|
+
Flipper.enabled?(:stats)
|
30
|
+
Flipper.enabled?(:search)
|
31
|
+
end
|
32
|
+
}
|
33
|
+
}.each(&:join)
|
data/examples/dsl.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
require 'flipper'
|
3
3
|
|
4
|
-
# create
|
4
|
+
# create an actor with an identifier
|
5
5
|
class Person < Struct.new(:id)
|
6
6
|
include Flipper::Identifier
|
7
7
|
end
|
@@ -47,20 +47,6 @@ puts "stats.enabled?: #{stats.enabled?}"
|
|
47
47
|
puts "stats.enabled? person: #{stats.enabled? person}"
|
48
48
|
puts
|
49
49
|
|
50
|
-
# get an instance of the percentage of time type set to 5
|
51
|
-
puts Flipper.time(5).inspect
|
52
|
-
|
53
|
-
# get an instance of the percentage of actors type set to 15
|
54
|
-
puts Flipper.actors(15).inspect
|
55
|
-
|
56
|
-
# get an instance of an actor using an object that responds to flipper_id
|
57
|
-
responds_to_flipper_id = Struct.new(:flipper_id).new(10)
|
58
|
-
puts Flipper.actor(responds_to_flipper_id).inspect
|
59
|
-
|
60
|
-
# get an instance of an actor using an object
|
61
|
-
thing = Struct.new(:flipper_id).new(22)
|
62
|
-
puts Flipper.actor(thing).inspect
|
63
|
-
|
64
50
|
# register a top level group
|
65
51
|
admins = Flipper.register(:admins) { |actor|
|
66
52
|
actor.respond_to?(:admin?) && actor.admin?
|
@@ -31,5 +31,7 @@ Flipper.enable_percentage_of_actors :pro_stats, 50
|
|
31
31
|
Flipper.enable_group :tweets, :admins
|
32
32
|
Flipper.enable_actor :posts, user2
|
33
33
|
|
34
|
-
pp Flipper.features.select { |feature| feature.enabled?(user1) }.map(&:name)
|
35
|
-
pp Flipper.features.select { |feature| feature.enabled?(user2) }.map(&:name)
|
34
|
+
pp Flipper.features.select { |feature| feature.enabled?(user1) }.map(&:name).sort
|
35
|
+
pp Flipper.features.select { |feature| feature.enabled?(user2) }.map(&:name).sort
|
36
|
+
pp Flipper.features.select { |feature| feature.enabled?(user1, user2) }.map(&:name).sort
|
37
|
+
pp Flipper.features.select { |feature| feature.enabled?([user2, user1]) }.map(&:name).sort
|