-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: yggdrasil engine #152
base: main
Are you sure you want to change the base?
Changes from 32 commits
fb3bdf8
eec8121
61ad46c
5797508
4b3a598
211fcdf
6382a94
a0707de
c39fe95
5df5067
f6071b9
88b46c7
7f55e6b
5851724
49925d5
0116bef
766d392
6530299
c367b0b
1cd34b2
5b5bb20
aaa6b0f
8f0c038
3122986
3e44bc3
05c83ce
e0d37af
156356c
9be1f29
8e64f84
cf89cc5
9dc382e
950eb8a
b7f1b7a
3fb4688
0518b74
92642d6
f143ca2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
require 'unleash/toggle_fetcher' | ||
require 'unleash/metrics_reporter' | ||
require 'unleash/scheduled_executor' | ||
require 'unleash/feature_toggle' | ||
require 'unleash/variant' | ||
require 'unleash/util/http' | ||
require 'logger' | ||
require 'time' | ||
|
@@ -11,14 +11,17 @@ module Unleash | |
class Client | ||
attr_accessor :fetcher_scheduled_executor, :metrics_scheduled_executor | ||
|
||
# rubocop:disable Metrics/AbcSize | ||
def initialize(*opts) | ||
Unleash.configuration = Unleash::Configuration.new(*opts) unless opts.empty? | ||
Unleash.configuration.validate! | ||
|
||
Unleash.logger = Unleash.configuration.logger.clone | ||
Unleash.logger.level = Unleash.configuration.log_level | ||
Unleash.engine = YggdrasilEngine.new | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've chosen to allow the client to new up Ygg, other consumers do nil checks when they want to access it - that's the metrics handling code and the fetching code |
||
Unleash.engine.register_custom_strategies(Unleash.configuration.strategies.custom_strategies) | ||
|
||
Unleash.toggle_fetcher = Unleash::ToggleFetcher.new | ||
Unleash.toggle_fetcher = Unleash::ToggleFetcher.new Unleash.engine | ||
if Unleash.configuration.disable_client | ||
Unleash.logger.warn "Unleash::Client is disabled! Will only return default (or bootstrapped if available) results!" | ||
Unleash.logger.warn "Unleash::Client is disabled! Metrics and MetricsReporter are also disabled!" | ||
|
@@ -30,6 +33,7 @@ def initialize(*opts) | |
start_toggle_fetcher | ||
start_metrics unless Unleash.configuration.disable_metrics | ||
end | ||
# rubocop:enable Metrics/AbcSize | ||
|
||
def is_enabled?(feature, context = nil, default_value_param = false, &fallback_blk) | ||
Unleash.logger.debug "Unleash::Client.is_enabled? feature: #{feature} with context #{context}" | ||
|
@@ -40,15 +44,16 @@ def is_enabled?(feature, context = nil, default_value_param = false, &fallback_b | |
default_value_param | ||
end | ||
|
||
toggle_as_hash = Unleash&.toggles&.select{ |toggle| toggle['name'] == feature }&.first | ||
if toggle_as_hash.nil? | ||
toggle_enabled = Unleash.engine.enabled?(feature, context) | ||
if toggle_enabled.nil? | ||
Unleash.logger.debug "Unleash::Client.is_enabled? feature: #{feature} not found" | ||
Unleash.engine.count_toggle(feature, false) | ||
return default_value | ||
end | ||
|
||
toggle = Unleash::FeatureToggle.new(toggle_as_hash, Unleash&.segment_cache) | ||
Unleash.engine.count_toggle(feature, toggle_enabled) | ||
|
||
toggle.is_enabled?(context) | ||
toggle_enabled | ||
end | ||
|
||
def is_disabled?(feature, context = nil, default_value_param = true, &fallback_blk) | ||
|
@@ -73,21 +78,27 @@ def if_disabled(feature, context = nil, default_value = true, &blk) | |
def get_variant(feature, context = Unleash::Context.new, fallback_variant = disabled_variant) | ||
Unleash.logger.debug "Unleash::Client.get_variant for feature: #{feature} with context #{context}" | ||
|
||
toggle_as_hash = Unleash&.toggles&.select{ |toggle| toggle['name'] == feature }&.first | ||
|
||
if toggle_as_hash.nil? | ||
toggle_enabled = Unleash.engine.enabled?(feature, context) | ||
if toggle_enabled.nil? | ||
Unleash.logger.debug "Unleash::Client.get_variant feature: #{feature} not found" | ||
Unleash.engine.count_toggle(feature, false) | ||
return fallback_variant | ||
end | ||
|
||
toggle = Unleash::FeatureToggle.new(toggle_as_hash) | ||
variant = toggle.get_variant(context, fallback_variant) | ||
Unleash.engine.count_toggle(feature, toggle_enabled) | ||
|
||
variant = Unleash.engine.get_variant(feature, context) | ||
|
||
if variant.nil? | ||
Unleash.logger.debug "Unleash::Client.get_variant variants for feature: #{feature} not found" | ||
Unleash.engine.count_variant(feature, "disabled") | ||
return fallback_variant | ||
end | ||
|
||
variant = Variant.new(variant) | ||
|
||
Unleash.engine.count_variant(feature, variant.name) | ||
|
||
# TODO: Add to README: name, payload, enabled (bool) | ||
|
||
variant | ||
|
@@ -117,7 +128,7 @@ def info | |
'appName': Unleash.configuration.app_name, | ||
'instanceId': Unleash.configuration.instance_id, | ||
'sdkVersion': "unleash-client-ruby:" + Unleash::VERSION, | ||
'strategies': Unleash.strategies.keys, | ||
'strategies': Unleash.strategies.known_strategies, | ||
'started': Time.now.iso8601(Unleash::TIME_RESOLUTION), | ||
'interval': Unleash.configuration.metrics_interval_in_millis | ||
} | ||
|
@@ -136,7 +147,6 @@ def start_toggle_fetcher | |
end | ||
|
||
def start_metrics | ||
Unleash.toggle_metrics = Unleash::Metrics.new | ||
Unleash.reporter = Unleash::MetricsReporter.new | ||
self.metrics_scheduled_executor = Unleash::ScheduledExecutor.new( | ||
'MetricsReporter', | ||
|
@@ -162,7 +172,7 @@ def register | |
end | ||
|
||
def disabled_variant | ||
@disabled_variant ||= Unleash::FeatureToggle.disabled_variant | ||
@disabled_variant ||= Unleash::Variant.disabled_variant | ||
end | ||
|
||
def first_fetch_is_eager | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,9 +40,9 @@ def metrics_interval_in_millis | |
def validate! | ||
return if self.disable_client | ||
|
||
raise ArgumentError, "URL and app_name are required parameters." if self.app_name.nil? || self.url.nil? | ||
raise ArgumentError, "app_name is a required parameter." if self.app_name.nil? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bootstrap only should be a viable option (we can do this in the others), relaxing this constraint makes testing a ton easier but I may be able to roll this one back if we need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Valid point. |
||
|
||
validate_custom_http_headers!(self.custom_http_headers) | ||
validate_custom_http_headers!(self.custom_http_headers) unless self.url.nil? | ||
end | ||
|
||
def refresh_backup_file! | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,22 @@ def to_s | |
",app_name=#{@app_name},environment=#{@environment}>" | ||
end | ||
|
||
def as_json | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For Yggdrasil to use so we can send the context as a JSON blob |
||
{ | ||
appName: self.app_name, | ||
environment: self.environment, | ||
userId: self.user_id, | ||
sessionId: self.session_id, | ||
remoteAddress: self.remote_address, | ||
currentTime: self.current_time, | ||
properties: self.properties | ||
} | ||
end | ||
|
||
def to_json(*options) | ||
as_json(*options).to_json(*options) | ||
end | ||
|
||
def to_h | ||
ATTRS.map{ |attr| [attr, self.send(attr)] }.to_h.merge(properties: @properties) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Belongs in the Rubocop config but we probably can't get away from this one. It's the only warning generated by this PR but this initialize is literally already at the limit