Class: Optimizely::OptimizelyUserContext

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

Defined Under Namespace

Classes: OptimizelyDecisionContext, OptimizelyForcedDecision

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(optimizely_client, user_id, user_attributes, identify: true) ⇒ OptimizelyUserContext

Returns a new instance of OptimizelyUserContext.



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/optimizely/optimizely_user_context.rb', line 29

def initialize(optimizely_client, user_id, user_attributes, identify: true)
  @attr_mutex = Mutex.new
  @forced_decision_mutex = Mutex.new
  @qualified_segment_mutex = Mutex.new
  @optimizely_client = optimizely_client
  @user_id = user_id
  @user_attributes = user_attributes.nil? ? {} : user_attributes.clone
  @forced_decisions = {}
  @qualified_segments = nil

  @optimizely_client&.identify_user(user_id: user_id) if identify
end

Instance Attribute Details

#forced_decisionsObject (readonly)

Representation of an Optimizely User Context using which APIs are to be called.



25
26
27
# File 'lib/optimizely/optimizely_user_context.rb', line 25

def forced_decisions
  @forced_decisions
end

#optimizely_clientObject (readonly)

Representation of an Optimizely User Context using which APIs are to be called.



25
26
27
# File 'lib/optimizely/optimizely_user_context.rb', line 25

def optimizely_client
  @optimizely_client
end

#user_idObject (readonly)

Representation of an Optimizely User Context using which APIs are to be called.



25
26
27
# File 'lib/optimizely/optimizely_user_context.rb', line 25

def user_id
  @user_id
end

Instance Method Details

#as_jsonObject



169
170
171
172
173
174
# File 'lib/optimizely/optimizely_user_context.rb', line 169

def as_json
  {
    user_id: @user_id,
    attributes: @user_attributes
  }
end

#cloneObject



42
43
44
45
46
47
# File 'lib/optimizely/optimizely_user_context.rb', line 42

def clone
  user_context = OptimizelyUserContext.new(@optimizely_client, @user_id, user_attributes, identify: false)
  @forced_decision_mutex.synchronize { user_context.instance_variable_set('@forced_decisions', @forced_decisions.dup) unless @forced_decisions.empty? }
  @qualified_segment_mutex.synchronize { user_context.instance_variable_set('@qualified_segments', @qualified_segments.dup) unless @qualified_segments.nil? }
  user_context
end

#decide(key, options = nil) ⇒ OptimizelyDecision

Returns a decision result (OptimizelyDecision) for a given flag key and a user context, which contains all data required to deliver the flag.

If the SDK finds an error, it’ll return a ‘decision` with nil for `variation_key`. The decision will include an error message in `reasons`

Parameters:

  • key

    -A flag key for which a decision will be made

  • options (defaults to: nil)
    • A list of options for decision making.

Returns:

  • (OptimizelyDecision)

    A decision result



71
72
73
# File 'lib/optimizely/optimizely_user_context.rb', line 71

def decide(key, options = nil)
  @optimizely_client&.decide(clone, key, options)
end

#decide_all(options = nil) ⇒ Object

Returns a hash of decision results (OptimizelyDecision) for all active flag keys.

Parameters:

  • options (defaults to: nil)
    • A list of options for decision making.

Returns:

    • Hash of decisions containing flag keys as hash keys and corresponding decisions as their values.



95
96
97
# File 'lib/optimizely/optimizely_user_context.rb', line 95

def decide_all(options = nil)
  @optimizely_client&.decide_all(clone, options)
end

#decide_for_keys(keys, options = nil) ⇒ Object

Returns a hash of decision results (OptimizelyDecision) for multiple flag keys and a user context.

If the SDK finds an error for a key, the response will include a decision for the key showing ‘reasons` for the error. The SDK will always return hash of decisions. When it can not process requests, it’ll return an empty hash after logging the errors.

Parameters:

  • keys
    • A list of flag keys for which the decisions will be made.

  • options (defaults to: nil)
    • A list of options for decision making.

Returns:

    • Hash of decisions containing flag keys as hash keys and corresponding decisions as their values.



85
86
87
# File 'lib/optimizely/optimizely_user_context.rb', line 85

def decide_for_keys(keys, options = nil)
  @optimizely_client&.decide_for_keys(clone, keys, options)
end

#fetch_qualified_segments(options: [], &block) ⇒ Object

Fetch all qualified segments for the user context.

The segments fetched will be saved in ‘@qualified_segments` and can be accessed any time.

Parameters:

  • options (defaults to: [])
    • A set of options for fetching qualified segments (optional).

  • block
    • An optional block to call after segments have been fetched.

    If a block is provided, segments will be fetched on a separate thread. Block will be called with a boolean indicating if the fetch succeeded.

Returns:

  • If no block is provided, a boolean indicating whether the fetch was successful. Otherwise, returns a thread handle and the status boolean is passed to the block.



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/optimizely/optimizely_user_context.rb', line 222

def fetch_qualified_segments(options: [], &block)
  fetch_segments = lambda do |opts, callback|
    segments = @optimizely_client&.fetch_qualified_segments(user_id: @user_id, options: opts)
    self.qualified_segments = segments
    success = !segments.nil?
    callback&.call(success)
    success
  end

  if block_given?
    Thread.new(options, block, &fetch_segments)
  else
    fetch_segments.call(options, nil)
  end
end

#find_forced_decision(context) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/optimizely/optimizely_user_context.rb', line 115

def find_forced_decision(context)
  return nil if @forced_decisions.empty?

  decision = nil
  @forced_decision_mutex.synchronize { decision = @forced_decisions[context] }
  decision
end

#get_forced_decision(context) ⇒ Object

Returns the forced decision for a given flag and an optional rule.

Parameters:

  • context
    • An OptimizelyDecisionContext object containg flag key and rule key.

Returns:

    • A variation key or nil if forced decisions are not set for the parameters.



129
130
131
# File 'lib/optimizely/optimizely_user_context.rb', line 129

def get_forced_decision(context)
  find_forced_decision(context)
end

#qualified_for?(segment) ⇒ Boolean

Checks if user is qualified for the provided segment.

Parameters:

  • segment
    • A segment name

Returns:

  • (Boolean)

    true if qualified.



201
202
203
204
205
206
207
208
209
# File 'lib/optimizely/optimizely_user_context.rb', line 201

def qualified_for?(segment)
  qualified = false
  @qualified_segment_mutex.synchronize do
    break if @qualified_segments.nil? || @qualified_segments.empty?

    qualified = @qualified_segments.include?(segment)
  end
  qualified
end

#qualified_segmentsObject

Returns An array of qualified segments for this user

Returns:

    • An array of segments names.



184
185
186
# File 'lib/optimizely/optimizely_user_context.rb', line 184

def qualified_segments
  @qualified_segment_mutex.synchronize { @qualified_segments.clone }
end

#qualified_segments=(segments) ⇒ Object

Replace qualified segments with provided segments

Parameters:

  • segments
    • An array of segment names



192
193
194
# File 'lib/optimizely/optimizely_user_context.rb', line 192

def qualified_segments=(segments)
  @qualified_segment_mutex.synchronize { @qualified_segments = segments.clone }
end

#remove_all_forced_decisionsObject

Removes all forced decisions bound to this user context.

Returns:

    • true if forced decisions have been removed successfully.



154
155
156
157
158
159
# File 'lib/optimizely/optimizely_user_context.rb', line 154

def remove_all_forced_decisions
  return false if @optimizely_client&.get_optimizely_config.nil?

  @forced_decision_mutex.synchronize { @forced_decisions.clear }
  true
end

#remove_forced_decision(context) ⇒ Object

Removes the forced decision for a given flag and an optional rule.

Parameters:

  • context
    • An OptimizelyDecisionContext object containg flag key and rule key.

Returns:

    • true if the forced decision has been removed successfully.



139
140
141
142
143
144
145
146
147
148
# File 'lib/optimizely/optimizely_user_context.rb', line 139

def remove_forced_decision(context)
  deleted = false
  @forced_decision_mutex.synchronize do
    if @forced_decisions.key?(context)
      @forced_decisions.delete(context)
      deleted = true
    end
  end
  deleted
end

#set_attribute(attribute_key, attribute_value) ⇒ Object

Set an attribute for a given key

Parameters:

  • key
    • An attribute key

  • value
    • An attribute value



58
59
60
# File 'lib/optimizely/optimizely_user_context.rb', line 58

def set_attribute(attribute_key, attribute_value)
  @attr_mutex.synchronize { @user_attributes[attribute_key] = attribute_value }
end

#set_forced_decision(context, decision) ⇒ Object

Sets the forced decision (variation key) for a given flag and an optional rule.

Parameters:

  • context
    • An OptimizelyDecisionContext object containg flag key and rule key.

  • decision
    • An OptimizelyForcedDecision object containing variation key

Returns:

    • true if the forced decision has been set successfully.



106
107
108
109
110
111
112
113
# File 'lib/optimizely/optimizely_user_context.rb', line 106

def set_forced_decision(context, decision)
  flag_key = context[:flag_key]
  return false if flag_key.nil?

  @forced_decision_mutex.synchronize { @forced_decisions[context] = decision }

  true
end

#to_json(*args) ⇒ Object



176
177
178
# File 'lib/optimizely/optimizely_user_context.rb', line 176

def to_json(*args)
  as_json.to_json(*args)
end

#track_event(event_key, event_tags = nil) ⇒ Object

Track an event

Parameters:

  • event_key
    • Event key representing the event which needs to be recorded.



165
166
167
# File 'lib/optimizely/optimizely_user_context.rb', line 165

def track_event(event_key, event_tags = nil)
  @optimizely_client&.track(event_key, @user_id, user_attributes, event_tags)
end

#user_attributesObject



49
50
51
# File 'lib/optimizely/optimizely_user_context.rb', line 49

def user_attributes
  @attr_mutex.synchronize { @user_attributes.clone }
end