class Rox::Core::ExperimentsExtensions

Public Class Methods

new(parser, target_groups_repository, flags_repository, experiment_repository) click to toggle source
# File lib/rox/core/repositories/roxx/experiments_extensions.rb, line 6
def initialize(parser, target_groups_repository, flags_repository, experiment_repository)
  @parser = parser
  @target_groups_repository = target_groups_repository
  @flags_repository = flags_repository
  @experiment_repository = experiment_repository
end

Public Instance Methods

bucket(seed) click to toggle source
# File lib/rox/core/repositories/roxx/experiments_extensions.rb, line 72
def bucket(seed)
  bytes = Digest::MD5.digest(seed).bytes
  hash = (bytes[0] & 0xFF) | ((bytes[1] & 0xFF) << 8) | ((bytes[2] & 0xFF) << 16) | ((bytes[3] & 0xFF) << 24)
  hash &= 0xFFFFFFFF
  bucket = hash * 1.0 / (2**32 - 1)

  bucket == 1 ? 0 : bucket
end
extend() click to toggle source
# File lib/rox/core/repositories/roxx/experiments_extensions.rb, line 13
def extend
  @parser.add_operator('mergeSeed') do |_parser, stack, _context|
    seed1 = stack.pop
    seed2 = stack.pop
    stack.push("#{seed1}.#{seed2}")
  end

  @parser.add_operator('isInPercentage') do |_parser, stack, _context|
    percentage = stack.pop
    seed = stack.pop

    percentage = percentage.is_a?(Numeric) ? percentage : percentage.to_s.to_f

    bucket = bucket(seed)
    stack.push(bucket <= percentage)
  end

  @parser.add_operator('isInPercentageRange') do |_parser, stack, _context|
    percentage_low = stack.pop
    percentage_high = stack.pop
    seed = stack.pop

    percentage_low = percentage_low.is_a?(Numeric) ? percentage_low : percentage_low.to_s.to_f
    percentage_high = percentage_high.is_a?(Numeric) ? percentage_high : percentage_high.to_s.to_f

    bucket = bucket(seed)
    stack.push(percentage_low <= bucket && bucket < percentage_high)
  end

  @parser.add_operator('flagValue') do |parser, stack, context|
    feature_flag_identifier = stack.pop
    result = Flag::FLAG_FALSE_VALUE
    string = @flags_repository.flag(feature_flag_identifier)

    if string.nil?
      flags_experiment = @experiment_repository.experiment_by_flag(feature_flag_identifier)

      if !flags_experiment.nil? && !flags_experiment.condition.nil? && !flags_experiment.condition.empty?
        experiment_eval_result = parser.evaluate_expression(flags_experiment.condition, context).string_value
        result = experiment_eval_result if !experiment_eval_result.nil? && !experiment_eval_result.empty?
      end
    else
      result = string.value(context)
    end

    stack.push(result)
  end

  @parser.add_operator('isInTargetGroup') do |parser, stack, context|
    target_group_identifier = stack.pop
    target_group = @target_groups_repository.target_group(target_group_identifier)
    if target_group.nil?
      stack.push(false)
    else
      stack.push(parser.evaluate_expression(target_group.condition, context).bool_value)
    end
  end
end