8000 Fix: Some suggested changes related to ODP (#325) · optimizely/csharp-sdk@c6c86ae · GitHub
[go: up one dir, main page]

10000
Skip to content

Commit c6c86ae

Browse files
Fix: Some suggested changes related to ODP (#325)
* Some suggested changes to fix null pointer exception * - Removed batchsize support from ODP event manager - Made some general fixes * Flush previous event * reverting this change Co-authored-by: mnoman09 <m.nomanshoaib09@gmail.com>
1 parent 4653690 commit c6c86ae

File tree

7 files changed

+72
-64
lines changed

7 files changed

+72
-64
lines changed

OptimizelySDK/Odp/Enums.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public enum OdpUserKeyType
3232
/// </summary>
3333
public enum OdpSegmentOption
3434
{
35-
IgnoreCache = 0,
36-
ResetCache = 1,
35+
IGNORE_CACHE = 0,
36+
RESET_CACHE = 1,
3737
}
3838
}

OptimizelySDK/Odp/OdpEventManager.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ public void UpdateSettings(OdpConfig odpConfig)
358358
{
359359
return;
360360
}
361-
361+
Flush();
362362
_odpConfig = odpConfig;
363363

364364
if (_autoStart)
@@ -480,20 +480,15 @@ public OdpEventManager Build()
480480
var manager = new OdpEventManager();
481481
manager._eventQueue = _eventQueue;
482482
manager._odpEventApiManager = _odpEventApiManager;
483-
manager._flushInterval = _flushInterval < TimeSpan.Zero ?
484-
Constants.DEFAULT_FLUSH_INTERVAL :
485-
_flushInterval;
483+
manager._flushInterval = (_flushInterval != null && _flushInterval > TimeSpan.Zero) ? _flushInterval : Constants.DEFAULT_FLUSH_INTERVAL;
484+
manager._batchSize = (_flushInterval != null && _flushInterval == TimeSpan.Zero) ? 1 : Constants.DEFAULT_BATCH_SIZE;
486485
manager._timeoutInterval = _timeoutInterval <= TimeSpan.Zero ?
487486
Constants.DEFAULT_TIMEOUT_INTERVAL :
488487
_timeoutInterval;
489488
manager._logger = _logger ?? new NoOpLogger();
490489
manager._errorHandler = _errorHandler ?? new NoOpErrorHandler();
491490
manager._autoStart = _autoStart ?? true;
492491

493-
manager._batchSize = manager._flushInterval == TimeSpan.Zero ?
494-
1 :
495-
Constants.DEFAULT_BATCH_SIZE;
496-
497492
manager._validOdpDataTypes = new List<string>()
498493
{
499494
"Char",

OptimizelySDK/Odp/OdpManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public string[] FetchQualifiedSegments(string userId, List<OdpSegmentOption> opt
9393
return null;
9494
}
9595

96-
return SegmentManager.FetchQualifiedSegments(userId, options).ToArray();
96+
return SegmentManager.FetchQualifiedSegments(userId, options)?.ToArray();
9797
}
9898

9999
/// <summary>

OptimizelySDK/Odp/OdpSegmentApiManager.cs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -150,22 +150,7 @@ IEnumerable segmentsToCheck
150150
{
151151
return
152152
@"{
153-
""query"": ""{
154-
query($userId: String, $audiences: [String]) {
155-
{
156-
customer({userKey}: $userId) {
157-
audiences(subset: $audiences) {
158-
edges {
159-
node {
160-
name
161-
state
162-
}
163-
}
164-
}
165-
}
166-
}
167-
}
168-
}"",
153+
""query"": ""query($userId: String, $audiences: [String]) {customer({userKey}: $userId) {audiences(subset: $audiences) {edges {node {name state}}}}}"",
169154
""variables"" : {
170155
""userId"": ""{userValue}"",
171156
""audiences"": {audiences}
@@ -210,7 +195,7 @@ private string QuerySegments(string apiKey, string endpoint, string query)
210195
_logger.Log(LogLevel.ERROR,
211196
$"{AUDIENCE_FETCH_FAILURE_MESSAGE} ({Constants.NETWORK_ERROR_REASON})");
212197

213-
return default;
198+
return null;
214199
}
215200

216201
return response.Content.ReadAsStringAsync().Result;

OptimizelySDK/Odp/OdpSegmentManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ public List<string> FetchQualifiedSegments(string fsUserId,
101101
List<string> qualifiedSegments;
102102
var cacheKey = GetCacheKey(OdpUserKeyType.FS_USER_ID.ToString().ToLower(), fsUserId);
103103

104-
if (options.Contains(OdpSegmentOption.ResetCache))
104+
if (options.Contains(OdpSegmentOption.RESET_CACHE))
105105
{
106106
_segmentsCache.Reset();
107107
}
108108

109-
if (!options.Contains(OdpSegmentOption.IgnoreCache))
109+
if (!options.Contains(OdpSegmentOption.IGNORE_CACHE))
110110
{
111111
qualifiedSegments = _segmentsCache.Lookup(cacheKey);
112112
if (qualifiedSegments != null)
@@ -126,7 +126,7 @@ public List<string> FetchQualifiedSegments(string fsUserId,
126126
_odpConfig.SegmentsToCheck)?.
127127
ToList();
128128

129-
if (qualifiedSegments != null && !options.Contains(OdpSegmentOption.IgnoreCache))
129+
if (qualifiedSegments != null && !options.Contains(OdpSegmentOption.IGNORE_CACHE))
130130
{
131131
_segmentsCache.Save(cacheKey, qualifiedSegments);
132132
}

OptimizelySDK/Optimizely.cs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public Optimizely(string datafile,
166166
#if USE_ODP
167167
// No need to setup notification for datafile updates. This constructor
168168
// is for hardcoded datafile which should not be changed using this method.
169-
OdpManager.UpdateSettings(config.PublicKeyForOdp, config.HostForOdp,
169+
OdpManager?.UpdateSettings(config.PublicKeyForOdp, config.HostForOdp,
170170
config.Segments.ToList());
171171
#endif
172172
}
@@ -219,29 +219,28 @@ public Optimizely(ProjectConfigManager configManager,
219219
InitializeComponents(eventDispatcher, logger, errorHandler, userProfileService,
220220
notificationCenter, eventProcessor, defaultDecideOptions, odpManager);
221221

222-
if (ProjectConfigManager.CachedProjectConfig == null)
222+
var projectConfig = ProjectConfigManager.CachedProjectConfig;
223+
224+
if (ProjectConfigManager.CachedProjectConfig != null)
223225
{
224-
return;
226+
// in case Project config is instantly ava 10000 ilable
227+
OdpManager?.UpdateSettings(projectConfig.PublicKeyForOdp, projectConfig.HostForOdp,
228+
projectConfig.Segments.ToList());
225229
}
226-
227-
var projectConfig = ProjectConfigManager.CachedProjectConfig;
228-
229-
// in case if notification is lost.
230-
OdpManager?.UpdateSettings(projectConfig.PublicKeyForOdp, projectConfig.HostForOdp,
231-
projectConfig.Segments.ToList());
232-
233230
if (ProjectConfigManager.SdkKey != null)
234231
{
235-
NotificationCenterRegistry.
236-
GetNotificationCenter(ProjectConfigManager.SdkKey, logger)?.
237-
AddNotification(NotificationCenter.NotificationType.OptimizelyConfigUpdate,
238-
() =>
239-
{
240-
OdpManager?.UpdateSettings(projectConfig.PublicKeyForOdp,
241-
projectConfig.HostForOdp,
242-
projectConfig.Segments.ToList());
243-
});
232+
NotificationCenterRegistry.GetNotificationCenter(configManager.SdkKey, logger)?.
233+
AddNotification(NotificationCenter.NotificationType.OptimizelyConfigUpdate,
234+
() =>
235+
{
236+
projectConfig = ProjectConfigManager.CachedProjectConfig;
237+
238+
OdpManager?.UpdateSettings(projectConfig.PublicKeyForOdp,
239+
projectConfig.HostForOdp,
240+
projectConfig.Segments.ToList());
241+
});
244242
}
243+
245244
#else
246245
InitializeComponents(eventDispatcher, logger, errorHandler, userProfileService,
247246
notificationCenter, eventProcessor, defaultDecideOptions);
@@ -457,7 +456,7 @@ private Variation GetVariation(string experimentKey, string userId, ProjectConfi
457456
return null;
458457
userAttributes = userAttributes ?? new UserAttributes();
459458

460-
var userContext = CreateUserContext(userId, userAttributes);
459+
var userContext = CreateUserContextCopy(userId, userAttributes);
461460
var variation = DecisionService.GetVariation(experiment, userContext, config)?.
462461
ResultObject;
463462
var decisionInfo = new Dictionary<string, object>
@@ -586,7 +585,7 @@ public virtual bool IsFeatureEnabled(string featureKey, string userId,
586585
bool featureEnabled = false;
587586
var sourceInfo = new Dictionary<string, string>();
588587
var decision = DecisionService.
589-
GetVariationForFeature(featureFlag, CreateUserContext(userId, userAttributes),
588+
GetVariationForFeature(featureFlag, CreateUserContextCopy(userId, userAttributes),
590589
config).
591590
ResultObject;
592591
var variation = decision?.Variation;
@@ -706,7 +705,7 @@ public virtual T GetFeatureVariableValueForType<T>(string featureKey, string var
706705
var featureEnabled = false;
707706
var variableValue = featureVariable.DefaultValue;
708707
var decision = DecisionService.
709-
GetVariationForFeature(featureFlag, CreateUserContext(userId, userAttributes),
708+
GetVariationForFeature(featureFlag, CreateUserContextCopy(userId, userAttributes),
710709
config).
711710
ResultObject;
712711

@@ -892,6 +891,24 @@ public OptimizelyUserContext CreateUserContext(string userId,
892891
return new OptimizelyUserContext(this, userId, userAttributes, ErrorHandler, Logger);
893892
}
894893

894+
private OptimizelyUserContext CreateUserContextCopy(string userId,
895+
UserAttributes userAttributes = null
896+
)
897+
{
898+
var inputValues = new Dictionary<string, string>
899+
{
900+
{
901+
USER_ID, userId
902+
},
903+
};
904+
905+
if (!ValidateStringInputs(inputValues))
906+
return null;
907+
908+
909+
return new OptimizelyUserContext(this, userId, userAttributes, null, null, ErrorHandler, Logger, shouldIdentifyUser: false);
910+
}
911+
895912
/// <summary>
896913
/// Returns a decision result ({@link OptimizelyDecision}) for a given flag key and a user context, which contains all data required to deliver the flag.
897914
/// <ul>
@@ -1276,7 +1293,7 @@ public OptimizelyJSON GetAllFeatureVariables(string featureKey, string userId,
12761293

12771294
var featureEnabled = false;
12781295
var decisionResult = DecisionService.GetVariationForFeature(featureFlag,
1279-
CreateUserContext(userId, userAttributes), config);
1296+
CreateUserContextCopy(userId, userAttributes), config);
12801297
var variation = decisionResult.ResultObject?.Variation;
12811298

12821299
if (variation != null)

OptimizelySDK/OptimizelyUserContext.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,13 @@ public virtual string GetUserId()
126126
/// <returns>List of qualified segments</returns>
127127
public List<string> GetQualifiedSegments()
128128
{
129-
List<string> qualifiedSegmentsCopy;
129+
List<string> qualifiedSegmentsCopy = null;
130130
lock (mutex)
131131
{
132-
qualifiedSegmentsCopy = new List<string>(QualifiedSegments);
132+
if (QualifiedSegments != null)
133+
{
134+
qualifiedSegmentsCopy = new List<string>(QualifiedSegments);
135+
}
133136
}
134137

135138
return qualifiedSegmentsCopy;
@@ -143,8 +146,19 @@ public void SetQualifiedSegments(List<string> qualifiedSegments)
143146
{
144147
lock (mutex)
145148
{
146-
QualifiedSegments.Clear();
147-
QualifiedSegments.AddRange(qualifiedSegments);
149+
if (qualifiedSegments == null)
150+
{
151+
QualifiedSegments = null;
152+
}
153+
else if (QualifiedSegments == null)
154+
{
155+
QualifiedSegments = new List<string>(qualifiedSegments);
156+
}
157+
else
158+
{
159+
QualifiedSegments.Clear();
160+
QualifiedSegments.AddRange(qualifiedSegments);
161+
}
148162
}
149163
}
150164

@@ -157,7 +171,7 @@ public bool IsQualifiedFor(string segment)
157171
{
158172
lock (mutex)
159173
{
160-
return QualifiedSegments.Contains(segment);
174+
return QualifiedSegments?.Contains(segment) ?? false;
161175
}
162176
}
163177

@@ -173,11 +187,8 @@ public bool FetchQualifiedSegments(List<OdpSegmentOption> segmentOptions = null)
173187

174188
var success = segments != null;
175189

176-
if (success)
177-
{
178-
SetQualifiedSegments(segments.ToList());
179-
}
180-
190+
SetQualifiedSegments(segments?.ToList());
191+
181192
return success;
182193
}
183194

0 commit comments

Comments
 (0)
0