ruby_event_store-flipper 0.2.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 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: []