Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
4f8765b
feat(Decide): Add Optimizely User Context
oakbani Oct 21, 2020
a7b78d8
line at EOF
oakbani Oct 21, 2020
c5f138c
Merge branch 'master' into oakbani/decide/user-context
oakbani Oct 22, 2020
c8d3a35
feat(Decide): Add Decide API
oakbani Oct 23, 2020
f770ce7
fix
oakbani Oct 23, 2020
244c4f3
nil by []
oakbani Oct 23, 2020
1bd6df7
fix enabled
oakbani Oct 23, 2020
ddd5349
add to_json in entities
oakbani Oct 27, 2020
98ced8c
Made it work with
zashraf1985 Oct 30, 2020
e7366f4
fixed decide_all api
zashraf1985 Oct 30, 2020
03a397f
fixed decide_for_keys
zashraf1985 Nov 2, 2020
3e9e417
fixed some failing unit tests
zashraf1985 Nov 2, 2020
ab824c7
added some test cases
zashraf1985 Nov 3, 2020
507dac6
added decide temporary tags
zashraf1985 Nov 4, 2020
13833de
added pending to forcefully fail unfinished tests
zashraf1985 Nov 4, 2020
b981f64
added some unit tests for decide
zashraf1985 Nov 4, 2020
d102a14
added unit tests for decide api
zashraf1985 Nov 5, 2020
7fb2ddf
added tests for ignoring user profile service option
zashraf1985 Nov 6, 2020
16a509d
added few more tests and some cleanup
zashraf1985 Nov 6, 2020
f6437b7
added a null check before cloning attributes
zashraf1985 Nov 6, 2020
ac90cd0
simplified the null check
zashraf1985 Nov 6, 2020
4026855
changed array append to push to support old ruby versions
zashraf1985 Nov 6, 2020
d6be7c2
added support for ENABLED_FLAGS_ONLY decide option
zashraf1985 Nov 12, 2020
752114d
Added unit tests for decide_for_keys and decide_all
zashraf1985 Nov 13, 2020
ee32ee1
added flag decisions support in decide api
zashraf1985 Nov 13, 2020
57ac8a0
added getters to OptimizelyDecision
zashraf1985 Nov 13, 2020
a300b3e
Merge branch 'master' into oakbani/decide-internal
zashraf1985 Nov 17, 2020
0070d3b
added unit tests for flag decisionss support in decide API
zashraf1985 Nov 17, 2020
6727d30
added sdk ready check to all apis
zashraf1985 Nov 17, 2020
d9a5549
added a check to include reasons
zashraf1985 Nov 18, 2020
cd1648e
added decide reasons
zashraf1985 Nov 18, 2020
8ec1619
fixed a minor issue with decide reasons
zashraf1985 Nov 19, 2020
a041cb6
Merge branch 'master' into oakbani/decide-internal
zashraf1985 Nov 24, 2020
7d122a4
removed some logs from decide reasons
zashraf1985 Nov 24, 2020
c40237f
additional null check for optimizely object
zashraf1985 Nov 24, 2020
7f6d985
fixed failing FSC test for some events
zashraf1985 Nov 24, 2020
b793012
merged the send impression calls under one check
zashraf1985 Nov 25, 2020
0a38bdd
fixed failing FSC test
zashraf1985 Nov 25, 2020
c401588
modified some tests
zashraf1985 Nov 25, 2020
cffa963
added event payload tests
zashraf1985 Nov 26, 2020
43b14ee
Added tests for include_reasons
zashraf1985 Nov 26, 2020
245637e
fixed a test title
zashraf1985 Nov 26, 2020
b76af55
added unit tests for default_decide_options
zashraf1985 Nov 30, 2020
5057b3f
added sdk not ready tests for decide_all and decide_for_keys
zashraf1985 Nov 30, 2020
92afe26
incorporated some review changes
zashraf1985 Dec 7, 2020
1ef9539
added a synchronize block when setting attributes
zashraf1985 Dec 7, 2020
89c3d6b
Added doc comments
zashraf1985 Dec 8, 2020
315d4aa
lint fixes
zashraf1985 Dec 9, 2020
f58d8bd
clone and sync user attributes and context
zashraf1985 Dec 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions lib/optimizely/optimizely_user_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,30 @@ module Optimizely
class OptimizelyUserContext
# Representation of an Optimizely User Context using which APIs are to be called.

attr_reader :user_id, :user_attributes
attr_reader :user_id

def initialize(optimizely_client, user_id, user_attributes)
@set_attr_mutex = Mutex.new
@attr_mutex = Mutex.new
@optimizely_client = optimizely_client
@user_id = user_id
@user_attributes = user_attributes.nil? ? {} : user_attributes.clone
end

def clone
OptimizelyUserContext.new(@optimizely_client, @user_id, user_attributes)
end

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

# Set an attribute for a given key
#
# @param key - An attribute key
# @param value - An attribute value

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

# Returns a decision result (OptimizelyDecision) for a given flag key and a user context, which contains all data required to deliver the flag.
Expand All @@ -50,7 +58,7 @@ def set_attribute(attribute_key, attribute_value)
# @return [OptimizelyDecision] A decision result

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why passing clone, we already cloning user_attributes

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are two separate things.

  1. Clone is used to pass a full clone of userContext so that subsequect updates to attributes has no impact on in flight decisions and the final userContext object which is referred to in decision object has the same attribute information that was used for the decision.
  2. user_attributes cloning is for the scenario where some access user_attributes for some other use from out side. We want to make sure that the copy that they read is not mutated by setAttribute called somewherre later in the code.

end

# Returns a hash of decision results (OptimizelyDecision) for multiple flag keys and a user context.
Expand All @@ -64,7 +72,7 @@ def decide(key, options = nil)
# @return - Hash of decisions containing flag keys as hash keys and corresponding decisions as their values.

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

# Returns a hash of decision results (OptimizelyDecision) for all active flag keys.
Expand All @@ -74,15 +82,15 @@ def decide_for_keys(keys, options = nil)
# @return - Hash of decisions containing flag keys as hash keys and corresponding decisions as their values.

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

# Track an event
#
# @param event_key - Event key representing the event which needs to be recorded.

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

def as_json
Expand Down