Module: LaunchDarkly::Impl::EvaluatorBucketing
- Defined in:
- lib/ldclient-rb/impl/evaluator_bucketing.rb
Overview
Encapsulates the logic for percentage rollouts.
Class Method Summary collapse
-
.bucket_user(user, key, bucket_by, salt, seed) ⇒ Number
Returns a user’s bucket value as a floating-point value in ‘[0, 1)`.
-
.variation_index_for_user(flag, rule, user) ⇒ Number
Applies either a fixed variation or a rollout for a rule (or the fallthrough rule).
Class Method Details
.bucket_user(user, key, bucket_by, salt, seed) ⇒ Number
Returns a user’s bucket value as a floating-point value in ‘[0, 1)`.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/ldclient-rb/impl/evaluator_bucketing.rb', line 56 def self.bucket_user(user, key, bucket_by, salt, seed) return nil unless user[:key] id_hash = bucketable_string_value(EvaluatorOperators.user_value(user, bucket_by)) if id_hash.nil? return 0.0 end if user[:secondary] id_hash += "." + user[:secondary].to_s end if seed hash_key = "%d.%s" % [seed, id_hash] else hash_key = "%s.%s.%s" % [key, salt, id_hash] end hash_val = (Digest::SHA1.hexdigest(hash_key))[0..14] hash_val.to_i(16) / Float(0xFFFFFFFFFFFFFFF) end |
.variation_index_for_user(flag, rule, user) ⇒ Number
Applies either a fixed variation or a rollout for a rule (or the fallthrough rule).
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/ldclient-rb/impl/evaluator_bucketing.rb', line 12 def self.variation_index_for_user(flag, rule, user) variation = rule[:variation] return variation, false if !variation.nil? # fixed variation rollout = rule[:rollout] return nil, false if rollout.nil? variations = rollout[:variations] if !variations.nil? && variations.length > 0 # percentage rollout bucket_by = rollout[:bucketBy].nil? ? "key" : rollout[:bucketBy] seed = rollout[:seed] bucket = bucket_user(user, flag[:key], bucket_by, flag[:salt], seed) # may not be present sum = 0; variations.each do |variate| if rollout[:kind] == "experiment" && !variate[:untracked] in_experiment = true end sum += variate[:weight].to_f / 100000.0 if bucket < sum return variate[:variation], !!in_experiment end end # The user's bucket value was greater than or equal to the end of the last bucket. This could happen due # to a rounding error, or due to the fact that we are scaling to 100000 rather than 99999, or the flag # data could contain buckets that don't actually add up to 100000. Rather than returning an error in # this case (or changing the scaling, which would potentially change the results for *all* users), we # will simply put the user in the last bucket. last_variation = variations[-1] in_experiment = rollout[:kind] == "experiment" && !last_variation[:untracked] [last_variation[:variation], in_experiment] else # the rule isn't well-formed [nil, false] end end |