Class: Optimizely::DecisionService

Inherits:
Object
  • Object
show all
Defined in:
lib/optimizely/decision_service.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, user_profile_service = nil) ⇒ DecisionService

Returns a new instance of DecisionService.



35
36
37
38
39
# File 'lib/optimizely/decision_service.rb', line 35

def initialize(config,  = nil)
  @config = config
  @user_profile_service = 
  @bucketer = Bucketer.new(@config)
end

Instance Attribute Details

#bucketerObject (readonly)

Optimizely’s decision service that determines into which variation of an experiment a user will be allocated.

The decision service contains all logic relating to how a user bucketing decisions is made. This includes all of the following (in order):

  1. Check experiment status

  2. Check forced bucketing

  3. Check whitelisting

  4. Check user profile service for past bucketing decisions (sticky bucketing)

  5. Check audience targeting

  6. Use Murmurhash3 to bucket the user



32
33
34
# File 'lib/optimizely/decision_service.rb', line 32

def bucketer
  @bucketer
end

#configObject (readonly)

Returns the value of attribute config.



33
34
35
# File 'lib/optimizely/decision_service.rb', line 33

def config
  @config
end

Instance Method Details

#get_variation(experiment_key, user_id, attributes = nil) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/optimizely/decision_service.rb', line 41

def get_variation(experiment_key, user_id, attributes = nil)
  # Determines variation into which user will be bucketed.
  #
  # experiment_key - Experiment for which visitor variation needs to be determined
  # user_id - String ID for user
  # attributes - Hash representing user attributes
  #
  # Returns variation ID where visitor will be bucketed (nil if experiment is inactive or user does not meet audience conditions)

  # Check to make sure experiment is active
  experiment = @config.get_experiment_from_key(experiment_key)
  if experiment.nil?
    return nil
  end

  experiment_id = experiment['id']
  unless @config.experiment_running?(experiment)
    @config.logger.log(Logger::INFO, "Experiment '#{experiment_key}' is not running.")
    return nil
  end

  # Check if a forced variation is set for the user
  forced_variation = @config.get_forced_variation(experiment_key, user_id)
  return forced_variation['id'] if forced_variation

  # Check if user is in a white-listed variation
  whitelisted_variation_id = get_whitelisted_variation_id(experiment_key, user_id)
  return whitelisted_variation_id if whitelisted_variation_id

  # Check for saved bucketing decisions
   = (user_id)
  saved_variation_id = get_saved_variation_id(experiment_id, )
  if saved_variation_id
    @config.logger.log(
      Logger::INFO,
      "Returning previously activated variation ID #{saved_variation_id} of experiment '#{experiment_key}' for user '#{user_id}' from user profile."
    )
    return saved_variation_id
  end

  # Check audience conditions
  unless Audience.user_in_experiment?(@config, experiment, attributes)
    @config.logger.log(
      Logger::INFO,
      "User '#{user_id}' does not meet the conditions to be in experiment '#{experiment_key}'."
    )
    return nil
  end

  # Bucket normally
  variation = @bucketer.bucket(experiment, user_id)
  variation_id = variation ? variation['id'] : nil

  # Persist bucketing decision
  (, experiment_id, variation_id)
  variation_id
end