-
Notifications
You must be signed in to change notification settings - Fork 31
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
Fix: Added notificationRegistry to make sure that odpSettings updates #501
Conversation
…call upon UpdateConfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Some changes suggested.
@@ -127,7 +128,12 @@ private Optimizely(@Nonnull EventHandler eventHandler, | |||
if (getProjectConfig() != null) { | |||
updateODPSettings(); | |||
} | |||
addUpdateConfigNotificationHandler(configNotification -> { updateODPSettings(); }); | |||
if (projectConfigManager != null) { | |||
NotificationRegistry.getNotificationCenter(projectConfigManager.getSDKKey()). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be confusing with with public NotificationCenter. What about changing names to
NotificationRegistry.getInternalNotificationCenter
or some other names to avoid confusion?
@msohailhussain What do you think?
@@ -23,5 +23,7 @@ public interface ProjectConfigManager { | |||
* @return ProjectConfig | |||
*/ | |||
ProjectConfig getConfig(); | |||
|
|||
String getSDKKey(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get sdkKey via getConfig().getSDKKey()
instead of adding the new inferface?
This will be convenient but we want to avoid any breaking changes with this new method here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see this comment. It will make sure that even when the config is not fetched, notificationCenter will contain the handler, which updates the ODPConfig.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mnoman09 Got it! Can we add a default implementation of this method (returning null), so no changes required for existing implementations. They'll all share the same internal notificationCenter for "null" sdkKey (until they fix it), which looks safe to me.
I believe the default interface method is supported in Java8 and also supported in android.
@@ -73,11 +74,13 @@ private HttpProjectConfigManager(long period, | |||
String datafileAccessToken, | |||
long blockingTimeoutPeriod, | |||
TimeUnit blockingTimeoutUnit, | |||
NotificationCenter notificationCenter) { | |||
NotificationCenter notificationCenter, | |||
String sdkKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also avoid this change as well if we can get sdkKey via ProjectConfig?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. We need to have sdkKey pass in here, to make sure that the when we call getSDKKey on projectConfigManager then we won't get it null in case if it is http config Manager.
@@ -127,7 +128,12 @@ private Optimizely(@Nonnull EventHandler eventHandler, | |||
if (getProjectConfig() != null) { | |||
updateODPSettings(); | |||
} | |||
addUpdateConfigNotificationHandler(configNotification -> { updateODPSettings(); }); | |||
if (projectConfigManager != null) { | |||
NotificationRegistry.getNotificationCenter(projectConfigManager.getSDKKey()). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaeopt we are getting sdkKey from projectConfigManager instead of getProjectConfig() because of Asynchronous call of httpConfigManager it might not able to add this NotificationHandler when projectConfig is not fetched.
Added default implementation of getSDKKey in ProjectConfigManager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All changes look great. A couple of more changes suggested.
@@ -153,6 +159,7 @@ public void close() { | |||
tryClose(eventProcessor); | |||
tryClose(eventHandler); | |||
tryClose(projectConfigManager); | |||
NotificationRegistry.clearNotificationCenterRegistry(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this safe to clear all notificationCenters? We can clear one for the current sdkKey. @msohailhussain also shared concern about memory leak when we close a notificationCenter, which may be addressed together when we clean it up.
@@ -127,7 +128,12 @@ private Optimizely(@Nonnull EventHandler eventHandler, | |||
if (getProjectConfig() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like my previous comment on this line got lost :)
We discussed this blocking "getProjectConfig" while constructing Optimizely is not desirable, so we need to make it return null if not available. @msohailhussain may have a good idea on how to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need one more change. See my comments.
@@ -124,10 +125,15 @@ private Optimizely(@Nonnull EventHandler eventHandler, | |||
|
|||
if (odpManager != null) { | |||
odpManager.getEventManager().start(); | |||
if (getProjectConfig() != null) { | |||
if (!(projectConfigManager instanceof PollingProjectConfigManager)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PollingProjectConfigManager can also have a preset projectConfig from a fallback datafile. In that case, we have to call updateODPSettings
for the projectConfig immediately (we may not get notification later if the fallback is updated already).
I think we can keep the getProjectConfig() != null
condition as before, with the change that `getProjectConfig() returns null immediately if config is not available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getProjectConfig() != null
condition is not possible without wait, with our current implementation. However, we can use the similar approach as we are using in Csharp, adding additional function of getCachedConfig()
in ProjectConfigManager
. Now the only concern I have, related to this approach, is that do we want to enforce its implementation or return null by default as we are doing for getSDKKey()
function?
In my opinion we should enforce it because if anyone uses custom ProjectConfigManager
without giving getCachedConfig
implementation then they won't be able use ODP as it only gets config using this new function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mnoman09 Agreed. Let's make them (getSdkKey
and getCachedConfig
) mandatory changes and keep them in the list of breaking changes for release.
…but the default implementation of it will return null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All changes look good to me!
A couple of small changes suggested - clarifications about required changes for existing custom configMangers. Android-sdk is one of them with tricky changes required.
core-api/src/main/java/com/optimizely/ab/config/ProjectConfigManager.java
Show resolved
Hide resolved
core-httpclient-impl/src/main/java/com/optimizely/ab/config/HttpProjectConfigManager.java
Outdated
Show resolved
Hide resolved
@mnoman09 It'll be great if we can have a note about these breaking changes so we do not miss them when releasing a major rev. |
…Key for a particular config is always same.
…icked from projectConfig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - See a couple of small changes to clean up.
sdkKey); | ||
|
||
httpProjectManager.setSdkKey(sdkKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this seSdkKey
is redundant? I see `sdkKey' parameter to the constructor (line 368).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will ensure that to trigger notification user provided sdkKey will always be prioritized, instead of what is available in ProjectConfig. This allows registry to always trigger notification even if the SDKKey is changed in the Projectconfig.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mnoman09 If we need this extra description for proper initializing sdkKey, this may be a source of issues. If you have to call setSdkKey() for proper overriding, can we remove sdkKey from constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already removed it from the HttpProjectConfigManager constructor if that is what you are asking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mnoman09 looks good!
core-api/src/main/java/com/optimizely/ab/config/PollingProjectConfigManager.java
Show resolved
Hide resolved
…hat to trigger the notification always user provided sdkKey will be prioritized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Summary
NOTE: breaking change
Anyone who is implementing custom ProjectConfigManager should now have to implement
getCachedConfig
andgetSdkKey
.Test plan
Issue
FSSDK-8769