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 +7 -0
- data/README.md +62 -0
- data/lib/generators/ruby_event_store/flipper/events_generator.rb +18 -0
- data/lib/generators/ruby_event_store/flipper/templates/events.rb +43 -0
- data/lib/ruby_event_store/flipper/events.rb +43 -0
- data/lib/ruby_event_store/flipper/version.rb +7 -0
- data/lib/ruby_event_store/flipper.rb +102 -0
- metadata +67 -0
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,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: []
|