Skip to content

feat(dfm): Integrate DFM with optimizely #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 48 commits into from
Jun 17, 2019

Conversation

msohailhussain
Copy link
Contributor

Summary

  • Added ProjectConfigManager in Optimizely class
  • Added OptimizelyFactory
  • Inside every API, replaced config with ProjectConfig Manager
  • Removed ProjectConfig from constructor
  • DecisionService using ProjectConfig with every method.
  • Removed ForcedVariation from ProjectConfig & DatafileProjectConfig
  • Moved ForcedVariation to DecisionService
  • Added GetVariation private method to use ProjectConfig given by Activate.
  • Updated existing unit tests

TODO:

  • Resolve TODOs (Mostly documentation & unit tests to be added)

Test plan

Issues

msohailhussain and others added 30 commits April 9, 2019 11:47
…rojectConfig as its implementation.

Created StaticProjectConfigManager and HttpProjectConfigManager for handling datafile retrievel.
Created PollingProjectConfigManager for retrieving ProjectConfig on the specified interval.
Added OnReady future in PollingProjectConfigManager class.
Added unit tests.
# Conflicts:
#	OptimizelySDK/DatafileManagement/DatafileProjectConfig.cs
# Conflicts:
#	OptimizelySDK/DatafileManagement/ProjectConfigManager.cs
#	OptimizelySDK/Optimizely.cs
# Conflicts:
#	OptimizelySDK.Net40/OptimizelySDK.Net40.csproj
#	OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj
#	OptimizelySDK.Tests/DecisionServiceTest.cs
#	OptimizelySDK.Tests/OptimizelySDK.Tests.csproj
#	OptimizelySDK.Tests/OptimizelyTest.cs
#	OptimizelySDK/Config/DatafileProjectConfig.cs
#	OptimizelySDK/Config/FallbackProjectConfigManager.cs
#	OptimizelySDK/Optimizely.cs
#	OptimizelySDK/OptimizelySDK.csproj
#	OptimizelySDK/ProjectConfig.cs
@msohailhussain msohailhussain changed the title feat(dfm): Integrate DFM with optimizely - WIP feat(dfm): Integrate DFM with optimizely Jun 12, 2019
@msohailhussain msohailhussain requested review from mikeproeng37, mjc1283 and a team June 12, 2019 19:40
Copy link

@mjc1283 mjc1283 left a comment

Choose a reason for hiding this comment

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

Is it possible to move forced variations to decision service in a separate PR? This one is large.

@msohailhussain
Copy link
Contributor Author

OK, I will separate out ForcedVariation, infact @mfahadahmed will do it.

@mfahadahmed mfahadahmed requested a review from mjc1283 June 13, 2019 08:59
/// <summary>
/// Implementation of ProjectConfigManager interface that simply
/// returns the stored ProjectConfig instance.
/// </summary>
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Also mention that it is static and the config it holds cannot change

Initialize(eventDispatcher, logger, errorHandler, userProfileService);
}

private void Initialize(IEventDispatcher eventDispatcher = null,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: InitializeComponents?

var config = ProjectConfigManager?.GetConfig();
if (!IsValid && config == null) {

Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'GetVariation'.");
Copy link
Contributor

Choose a reason for hiding this comment

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

... Failing 'IsFeatureEnabled'

return null;
}

return GetFeatureVariableValueForType<bool?>(featureKey, variableKey, userId, userAttributes, FeatureVariable.VariableType.BOOLEAN, config);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to pass the config to it? Why not have the GetFeatureVariableValueForType method use the ProjectConfigManager?

var config = ProjectConfigManager?.GetConfig();

if (!IsValid && config == null) {
Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'activate'.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Not activate but GetFeatureVariableBoolean

private void SendImpressionEvent(Experiment experiment, Variation variation, string userId,
UserAttributes userAttributes)
private void SendImpressionEvent(Experiment experiment, Variation variation, string userId,
UserAttributes userAttributes, ProjectConfig config)
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to take in the ProjectConfig as a param. We can use the ProjectConfigManager in here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method is used by Activate, if we use ProjectConfigManager inside SendImpressionEvent, there are chances ProjectConfig used to get variation from DecisionService may not be same when get from ProjectConfigManagr inside this method.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, ok that could actually happen.

namespace OptimizelySDK
{

/// TODO: Need to check with Mike, no need of this class
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not the case anymore right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, will add unit test and more convenience methods in separate PR. Removing this comment.

var errorHandler = new DefaultErrorHandler();
var eventDispatcher = new DefaultEventDispatcher(logger);
var builder = new HttpProjectConfigManager.Builder();
// don't block
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this doc comment for?

@@ -168,7 +190,8 @@ private bool ValidatePreconditions(Experiment experiment, string userId, UserAtt
/// <returns>null|Variation Representing variation</returns>
public Variation Activate(string experimentKey, string userId, UserAttributes userAttributes = null)
{
if (!IsValid)
var config = ProjectConfigManager?.GetConfig();
if (!IsValid && config == null)
Copy link

Choose a reason for hiding this comment

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

Should this (and the same check elsewhere) be using an or operator instead of and operator? I.e., !IsValid || config == null

Copy link
Contributor Author

@msohailhussain msohailhussain Jun 14, 2019

Choose a reason for hiding this comment

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

It should be AND, if isValid is false and also Config is null, then it's invalid.

Copy link

Choose a reason for hiding this comment

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

ProjectConfigManager.GetConfig can return null. When it does, we must return null early, otherwise attempting to access config.GetExperimentFromKey could crash. If I'm misunderstanding, let me know.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So IsValid will always be false if we are using ProjectConfigManager to initialize Optimizely instance.
Please let me know we can chat for more clarity.

Copy link
Contributor

Choose a reason for hiding this comment

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

Since we are opening up the ProjectConfigManager to be overriden, we should guard against the custom implementation not returning null or not setting isValid to false. Therefore I think the right apporach is to be more careful and use !IsValid || config == null like @mjc1283 suggested.

{

var config = ProjectConfigManager?.GetConfig();
if (!IsValid && config == null) {
Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'activate'.");
Copy link
Contributor

Choose a reason for hiding this comment

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

This still refers to activate. Please make sure it references the right API name.

@@ -18,7 +18,7 @@ namespace OptimizelySDK.Config
{
/// <summary>
/// Implementation of ProjectConfigManager interface that simply
/// returns the stored ProjectConfig instance.
/// returns the stored ProjectConfig instance which is mutable and cannot be changed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm this is confusing. The ProjectConfig in this manager should not be mutable.

@msohailhussain
Copy link
Contributor Author

@mikeng13 Please check my last commit, feedback addressed.

@@ -168,7 +190,8 @@ private bool ValidatePreconditions(Experiment experiment, string userId, UserAtt
/// <returns>null|Variation Representing variation</returns>
public Variation Activate(string experimentKey, string userId, UserAttributes userAttributes = null)
{
if (!IsValid)
var config = ProjectConfigManager?.GetConfig();
if (!IsValid && config == null)
Copy link

Choose a reason for hiding this comment

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

ProjectConfigManager.GetConfig can return null. When it does, we must return null early, otherwise attempting to access config.GetExperimentFromKey could crash. If I'm misunderstanding, let me know.

Copy link
Contributor

@mikeproeng37 mikeproeng37 left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link

@mjc1283 mjc1283 left a comment

Choose a reason for hiding this comment

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

LGTM, isValid changes look good.

@msohailhussain msohailhussain merged commit 5ed605f into sohail/dfmcomplete Jun 17, 2019
@msohailhussain msohailhussain deleted the sohail/optimizelydfm branch September 24, 2019 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants