ruby_event_store-flipper 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0c5ce25aa870798086c39153c8efdb84eb4d69b935058e42e61c1f4d11ce8c92
4
+ data.tar.gz: d2fc3133da101956ad78fc420fb96e62d09f31e32b5bfe794d4b4464831eaef7
5
+ SHA512:
6
+ metadata.gz: be360a15e185b781ea62d3b1ab887e8ad0c56d06d8680dbd5c80042798d71ef47aea4ee12fc60afea8defb8b024862c458475f6d13d064122f656039159ada02
7
+ data.tar.gz: 01e936c68c6094938e9b47d2fb215cecd032fccc8c586d07af04f69464ec98d04f71c06b8485ea00eb4f6074cf1a6abe5bfb66a024919afa263919ceb9ef5591
data/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # RubyEventStore::Flipper
2
+
3
+ Flipper integration for RubyEventStore.
4
+
5
+
6
+ ## Installation
7
+
8
+ 1. Ensure that your Flipper has instrumentation enabled
9
+ 2. Enable RubyEventStore subscriber via `RubyEventStore::Flipper.enable(event_store_instance)`
10
+
11
+ Example:
12
+
13
+ ```ruby
14
+ Flipper.configure do |config|
15
+ config.default do
16
+ # ... adapter configuration
17
+
18
+ # Enable instrumentation in Flipper
19
+ Flipper.new(adapter, instrumenter: ActiveSupport::Notifications)
20
+ end
21
+ end
22
+
23
+ # Enable RubyEventStore instrumentation for Flipper
24
+ RubyEventStore::Flipper.enable(Rails.configuration.event_store)
25
+ ```
26
+
27
+ ## Customize stream pattern
28
+
29
+ By default, stream name for toggle `foobar` is `FeatureToggle$foobar`. You can customize it via `stream_pattern` argument:
30
+
31
+ ```ruby
32
+ RubyEventStore::Flipper.enable(Rails.configuration.event_store, stream_pattern: ->(feature_name) { "feature_toggle-#{feature_name}" })
33
+ ```
34
+
35
+ ## Customize notifications component
36
+
37
+ Anything with the same API as `ActiveSupport::Notifications` is supported.
38
+
39
+ ```ruby
40
+ RubyEventStore::Flipper.enable(Rails.configuration.event_store, instrumenter: AS::Notifications)
41
+ ```
42
+
43
+ ## Customize events being used
44
+
45
+ You can pass your own events to be used instead of default ones. Example:
46
+
47
+ ```
48
+ Flipper.enable(event_store, custom_events: {
49
+ "ToggleAdded" => CustomModule::ToggleAdded,
50
+ "ToggleRemoved" => CustomModule::ToggleRemoved,
51
+ "ToggleGloballyEnabled" => CustomModule::ToggleGloballyEnabled,
52
+ "ToggleEnabledForActor" => CustomModule::ToggleEnabledForActor,
53
+ "ToggleEnabledForGroup" => CustomModule::ToggleEnabledForGroup,
54
+ "ToggleEnabledForPercentageOfActors" => CustomModule::ToggleEnabledForPercentageOfActors,
55
+ "ToggleEnabledForPercentageOfTime" => CustomModule::ToggleEnabledForPercentageOfTime,
56
+ "ToggleGloballyDisabled" => CustomModule::ToggleGloballyDisabled,
57
+ "ToggleDisabledForActor" => CustomModule::ToggleDisabledForActor,
58
+ "ToggleDisabledForGroup" => CustomModule::ToggleDisabledForGroup,
59
+ "ToggleDisabledForPercentageOfActors" => CustomModule::ToggleDisabledForPercentageOfActors,
60
+ "ToggleDisabledForPercentageOfTime" => CustomModule::ToggleDisabledForPercentageOfTime,
61
+ })
62
+ ```
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'rails/generators'
5
+ rescue LoadError
6
+ end
7
+
8
+ module RubyEventStore
9
+ module Flipper
10
+ class EventsGenerator < Rails::Generators::Base
11
+ source_root File.expand_path(File.join(File.dirname(__FILE__), './templates'))
12
+
13
+ def create_migration
14
+ template "events.rb", "app/models/ruby_event_store/flipper/events.rb"
15
+ end
16
+ end
17
+ end
18
+ end if defined?(Rails::Generators::Base)
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyEventStore
4
+ module Flipper
5
+ module Events
6
+ class ToggleAdded < RubyEventStore::Event
7
+ end
8
+
9
+ class ToggleRemoved < RubyEventStore::Event
10
+ end
11
+
12
+ class ToggleGloballyEnabled < RubyEventStore::Event
13
+ end
14
+
15
+ class ToggleGloballyDisabled < RubyEventStore::Event
16
+ end
17
+
18
+ class ToggleEnabledForActor < RubyEventStore::Event
19
+ end
20
+
21
+ class ToggleDisabledForActor < RubyEventStore::Event
22
+ end
23
+
24
+ class ToggleEnabledForGroup < RubyEventStore::Event
25
+ end
26
+
27
+ class ToggleDisabledForGroup < RubyEventStore::Event
28
+ end
29
+
30
+ class ToggleEnabledForPercentageOfActors < RubyEventStore::Event
31
+ end
32
+
33
+ class ToggleDisabledForPercentageOfActors < RubyEventStore::Event
34
+ end
35
+
36
+ class ToggleEnabledForPercentageOfTime < RubyEventStore::Event
37
+ end
38
+
39
+ class ToggleDisabledForPercentageOfTime < RubyEventStore::Event
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyEventStore
4
+ module Flipper
5
+ module Events
6
+ class ToggleAdded < RubyEventStore::Event
7
+ end
8
+
9
+ class ToggleRemoved < RubyEventStore::Event
10
+ end
11
+
12
+ class ToggleGloballyEnabled < RubyEventStore::Event
13
+ end
14
+
15
+ class ToggleGloballyDisabled < RubyEventStore::Event
16
+ end
17
+
18
+ class ToggleEnabledForActor < RubyEventStore::Event
19
+ end
20
+
21
+ class ToggleDisabledForActor < RubyEventStore::Event
22
+ end
23
+
24
+ class ToggleEnabledForGroup < RubyEventStore::Event
25
+ end
26
+
27
+ class ToggleDisabledForGroup < RubyEventStore::Event
28
+ end
29
+
30
+ class ToggleEnabledForPercentageOfActors < RubyEventStore::Event
31
+ end
32
+
33
+ class ToggleDisabledForPercentageOfActors < RubyEventStore::Event
34
+ end
35
+
36
+ class ToggleEnabledForPercentageOfTime < RubyEventStore::Event
37
+ end
38
+
39
+ class ToggleDisabledForPercentageOfTime < RubyEventStore::Event
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyEventStore
4
+ module Flipper
5
+ VERSION = "0.2.0"
6
+ end
7
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "flipper/version"
4
+ require "ruby_event_store"
5
+ require_relative "flipper/events"
6
+
7
+ module RubyEventStore
8
+ module Flipper
9
+ DEFAULT_STREAM_PATTERN = ->(feature_name) { "FeatureToggle$#{feature_name}" }
10
+
11
+ def self.enable(event_store, instrumenter: ActiveSupport::Notifications, stream_pattern: DEFAULT_STREAM_PATTERN, custom_events: nil)
12
+ instrumenter.subscribe("feature_operation.flipper", NotificationHandler.new(event_store, stream_pattern, custom_events))
13
+ end
14
+
15
+ class NotificationHandler
16
+ def initialize(event_store, stream_pattern, custom_events)
17
+ @event_store = event_store
18
+ @stream_pattern = stream_pattern
19
+ @custom_events = {
20
+ "ToggleAdded" => Events::ToggleAdded,
21
+ "ToggleRemoved" => Events::ToggleRemoved,
22
+ "ToggleGloballyEnabled" => Events::ToggleGloballyEnabled,
23
+ "ToggleEnabledForActor" => Events::ToggleEnabledForActor,
24
+ "ToggleEnabledForGroup" => Events::ToggleEnabledForGroup,
25
+ "ToggleEnabledForPercentageOfActors" => Events::ToggleEnabledForPercentageOfActors,
26
+ "ToggleEnabledForPercentageOfTime" => Events::ToggleEnabledForPercentageOfTime,
27
+ "ToggleGloballyDisabled" => Events::ToggleGloballyDisabled,
28
+ "ToggleDisabledForActor" => Events::ToggleDisabledForActor,
29
+ "ToggleDisabledForGroup" => Events::ToggleDisabledForGroup,
30
+ "ToggleDisabledForPercentageOfActors" => Events::ToggleDisabledForPercentageOfActors,
31
+ "ToggleDisabledForPercentageOfTime" => Events::ToggleDisabledForPercentageOfTime,
32
+ }.merge(custom_events || {})
33
+ end
34
+
35
+ def call(_name, _start, _finish, _id, payload)
36
+ feature_name = payload.fetch(:feature_name).to_s
37
+ operation = payload.fetch(:operation)
38
+ common_payload = { feature_name: feature_name }
39
+ event_store.publish(build_domain_event(common_payload, operation, payload), stream_name: stream_pattern.(feature_name))
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :event_store, :stream_pattern, :custom_events
45
+
46
+ def build_domain_event(common_payload, operation, payload)
47
+ case operation
48
+ when :add
49
+ event_klass("ToggleAdded").new(data: common_payload)
50
+ when :remove
51
+ event_klass("ToggleRemoved").new(data: common_payload)
52
+ when :enable
53
+ gate_name = payload.fetch(:gate_name)
54
+ thing = payload.fetch(:thing)
55
+ case gate_name
56
+ when :boolean
57
+ event_klass("ToggleGloballyEnabled").new(data: common_payload)
58
+ when :actor
59
+ event_klass("ToggleEnabledForActor").new(data: common_payload.merge(
60
+ actor: thing.value,
61
+ ))
62
+ when :group
63
+ event_klass("ToggleEnabledForGroup").new(data: common_payload.merge(
64
+ group: thing.value.to_s,
65
+ ))
66
+ when :percentage_of_actors
67
+ event_klass("ToggleEnabledForPercentageOfActors").new(data: common_payload.merge(
68
+ percentage: thing.value,
69
+ ))
70
+ when :percentage_of_time
71
+ event_klass("ToggleEnabledForPercentageOfTime").new(data: common_payload.merge(
72
+ percentage: thing.value,
73
+ ))
74
+ end
75
+ when :disable
76
+ gate_name = payload.fetch(:gate_name)
77
+ thing = payload.fetch(:thing)
78
+ case gate_name
79
+ when :boolean
80
+ event_klass("ToggleGloballyDisabled").new(data: common_payload)
81
+ when :actor
82
+ event_klass("ToggleDisabledForActor").new(data: common_payload.merge(
83
+ actor: thing.value,
84
+ ))
85
+ when :group
86
+ event_klass("ToggleDisabledForGroup").new(data: common_payload.merge(
87
+ group: thing.value.to_s,
88
+ ))
89
+ when :percentage_of_actors
90
+ event_klass("ToggleDisabledForPercentageOfActors").new(data: common_payload)
91
+ when :percentage_of_time
92
+ event_klass("ToggleDisabledForPercentageOfTime").new(data: common_payload)
93
+ end
94
+ end
95
+ end
96
+
97
+ def event_klass(event_name)
98
+ custom_events.fetch(event_name)
99
+ end
100
+ end
101
+ end
102
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby_event_store-flipper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Arkency
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby_event_store
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ description:
28
+ email: dev@arkency.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files:
32
+ - README.md
33
+ files:
34
+ - README.md
35
+ - lib/generators/ruby_event_store/flipper/events_generator.rb
36
+ - lib/generators/ruby_event_store/flipper/templates/events.rb
37
+ - lib/ruby_event_store/flipper.rb
38
+ - lib/ruby_event_store/flipper/events.rb
39
+ - lib/ruby_event_store/flipper/version.rb
40
+ homepage: https://railseventstore.org
41
+ licenses:
42
+ - MIT
43
+ metadata:
44
+ homepage_uri: https://railseventstore.org
45
+ source_code_uri: https://github.com/RailsEventStore/rails_event_store
46
+ bug_tracker_uri: https://github.com/RailsEventStore/rails_event_store/issues
47
+ rubygems_mfa_required: 'true'
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '2.6'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.2.22
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Flipper integration for RubyEventStore
67
+ test_files: []