Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
gardleopard committed Aug 22, 2023
1 parent 617dacc commit 78c1e48
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Install dependencies
run: bundle install
- name: Download test cases
run: git clone --depth 5 --branch v4.2.2 https://github.com/Unleash/client-specification.git client-specification
run: git clone --depth 5 --branch v4.3.1 https://github.com/Unleash/client-specification.git client-specification
- name: Run tests
run: bundle exec rake
env:
Expand Down
34 changes: 19 additions & 15 deletions lib/unleash/activation_strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,35 @@ def initialize(name, params, constraints = [], variants = [])
self.params = {}
end

if constraints.is_a?(Array) && constraints.each { |c| c.is_a?(Constraint) }
if constraints.is_a?(Array) && constraints.each{ |c| c.is_a?(Constraint) }
self.constraints = constraints
else
Unleash.logger.warn "Invalid constraints provided for ActivationStrategy (contraints: #{constraints})"
self.disabled = true
self.constraints = []
end

if variants.is_a?(Array)
self.variants = variants
.select { |v| v.is_a?(Hash) && v.has_key?("name") }
.map { |v|
VariantDefinition.new(
v.fetch("name", ""),
v.fetch("weight", 0),
v.fetch("payload", nil),
v.fetch("stickiness", nil),
v.fetch("overrides", [])
)
}
end
self.variants = initialize_variant_definitions(variants) if variants.is_a?(Array)
end

def matches_context?(context)
self.constraints.any? { |c| c.matches_context? context }
self.constraints.any?{ |c| c.matches_context? context }
end

private

def initialize_variant_definitions(variants)
variants
.select{ |v| v.is_a?(Hash) && v.has_key?("name") }
.map do |v|
VariantDefinition.new(
v.fetch("name", ""),
v.fetch("weight", 0),
v.fetch("payload", nil),
v.fetch("stickiness", nil),
v.fetch("overrides", [])
)
end
end
end
end
48 changes: 26 additions & 22 deletions lib/unleash/feature_toggle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ def get_variant(context, fallback_variant = Unleash::FeatureToggle.disabled_vari

toggle_enabled = am_enabled?(context)

variants = am_enabled(context)[:variants]
strategy = am_enabled(context)[:strategy]

variant = resolve_variant(context, toggle_enabled, variants)
group_id = strategy&.params&.fetch('groupId', self.name) || self.name
variants = strategy&.variants || self.variant_definitions

variant = resolve_variant(context, toggle_enabled, variants, group_id)

choice = toggle_enabled ? :yes : :no
Unleash.toggle_metrics.increment_variant(self.name, choice, variant.name) unless Unleash.configuration.disable_metrics
Expand All @@ -54,11 +57,11 @@ def self.disabled_variant

private

def resolve_variant(context, toggle_enabled, variants)
def resolve_variant(context, toggle_enabled, variants, group_id)
return Unleash::FeatureToggle.disabled_variant unless toggle_enabled
return Unleash::FeatureToggle.disabled_variant if sum_variant_defs_weights(variants) <= 0

variant_from_override_match(context, variants) || variant_from_weights(context, resolve_stickiness(variants), variants)
variant_from_override_match(context, variants) || variant_from_weights(context, resolve_stickiness(variants), variants, group_id)
end

def resolve_stickiness(variants)
Expand All @@ -71,27 +74,25 @@ def am_enabled?(context)
end

def am_enabled(context)
result = false
variants = self.variant_definitions
if self.enabled
if self.strategies.empty?
result = true
else
strategy = self.strategies.find(proc {false}){|s| (strategy_enabled?(s, context) && strategy_constraint_matches?(s, context))}
if strategy
variants = strategy.variants if strategy.variants
result = true
end
returnable = {
result: false,
strategy: nil
}
return returnable unless self.enabled

if self.strategies.empty?
returnable[:result] = true
else
returnable[:strategy] = self.strategies.find(proc{ nil }) do |s|
(strategy_enabled?(s, context) && strategy_constraint_matches?(s, context))
end
returnable[:result] = true if returnable[:strategy]
end

Unleash.logger.debug "Unleash::FeatureToggle (enabled:#{self.enabled} " \
"and Strategies combined with contraints returned #{result})"
"and Strategies combined with contraints returned #{returnable[:result]})"

{
result: result,
variants: variants
}
returnable
end

def strategy_enabled?(strategy, context)
Expand Down Expand Up @@ -131,8 +132,11 @@ def variant_from_override_match(context, variants)
Unleash::Variant.new(name: variant.name, enabled: true, payload: variant.payload)
end

def variant_from_weights(context, stickiness, variants)
variant_weight = Unleash::Strategy::Util.get_normalized_number(variant_salt(context, stickiness), self.name, sum_variant_defs_weights(variants))
def variant_from_weights(context, stickiness, variants, group_id)
variant_weight = Unleash::Strategy::Util.get_normalized_number(
variant_salt(context, stickiness), group_id,
sum_variant_defs_weights(variants)
)
prev_weights = 0

variant_definition = variants
Expand Down
9 changes: 9 additions & 0 deletions lib/unleash/variant_definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@

module Unleash
class VariantDefinition
include Comparable
attr_accessor :name, :weight, :payload, :overrides, :stickiness

def ==(other)
self.name == other.name &&
self.weight == other.weight &&
self.payload == other.payload &&
self.stickiness == other.stickiness &&
self.overrides == other.overrides
end

def initialize(name, weight = 0, payload = nil, stickiness = nil, overrides = []) # rubocop:disable Metrics/ParameterLists
self.name = name
self.weight = weight
Expand Down
5 changes: 4 additions & 1 deletion spec/unleash/activation_strategy_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'unleash/constraint'
require 'unleash/variant_definition'

RSpec.describe Unleash::ActivationStrategy do
before do
Expand All @@ -12,15 +13,17 @@
context 'with correct payload' do
let(:params) { Hash.new(test: true) }
let(:constraints) { [Unleash::Constraint.new("constraint_name", "IN", ["value"])] }
let(:variants) { [Unleash::VariantDefinition.new("variant_name")] }

it 'initializes with correct attributes' do
expect(Unleash.logger).to_not receive(:warn)

strategy = Unleash::ActivationStrategy.new(name, params, constraints)
strategy = Unleash::ActivationStrategy.new(name, params, constraints, [{ "name" => "variant_name" }])

expect(strategy.name).to eq name
expect(strategy.params).to eq params
expect(strategy.constraints).to eq constraints
expect(strategy.variants).to eq variants
end
end

Expand Down

0 comments on commit 78c1e48

Please sign in to comment.