-
Notifications
You must be signed in to change notification settings - Fork 83
feat(flag-decisions): Add support for sending flag decisions #599
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
Conversation
This pr depends on #601. |
Include metaData in ImpressionEvent Send decisions when variation is null Update existing event_helpers tests Add metadata to impressionEventParams in getImpressionEventParams method Add ruleKey parameter to ImpressionEvent Change experimentKey to ruleKey Update existing unit tests Remove sendFlagDecisions from common event params Update event-processor to include metadata in makeDecisionSnapshot Update event-processos variationKey type to string | null Update variationKey type to string | null Update existing optimizely module tests part 1 Start adding new tests Update unit tests impression params when decision.experiment is undefined Clean up Change layer id type to be string | null Update variationId to bull as default
88b84dc
to
865b852
Compare
8608a7b
to
dd43047
Compare
dd43047
to
c4d1d51
Compare
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.
My main suggestion is to try passing around the decision object that includes as much as possible (experiment, variation, rule key, rule type, etc.). The potential benefit is to reduce the number of additional parameters and repeated checking for null/empty string.
experimentKey: string, | ||
variationKey: string, | ||
flagKey: string, | ||
ruleType: string, |
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.
flagKey
and ruleType
have been added as new parameters here, so they can be passed on down to emitNotificationCenterActivate
and buildImpressionEvent
. We have 3 new functions that all need this new data.
All these functions need experimentKey
, variationKey
, flagKey
, and ruleType
. When it's called from isFeatureEnabled
, these originate from the decision object.
What if instead we passed around the decision
object instead of these 4 individual values? This refactoring would take a little work, but the result could be cleaner. We may be able to eliminate some of the repetitive checking of keys for null or empty string. Decision
could even become a class with methods if we wanted to avoid repeating such checks (i.e. something like decision.getExperimentKey()
).
@@ -641,6 +677,29 @@ export default class Optimizely { | |||
const decision = this.decisionService.getVariationForFeature(configObj, feature, userId, attributes); | |||
const variation = decision.variation; | |||
|
|||
if ( | |||
decision.decisionSource === DECISION_SOURCES.ROLLOUT && | |||
projectConfig.getSendFlagDecisionsValue(configObj) === true |
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.
getSendFlagDecisions
returns a boolean.
projectConfig.getSendFlagDecisionsValue(configObj) === true | |
projectConfig.getSendFlagDecisionsValue(configObj) |
let experimentKey = ''; | ||
if (decision.experiment !== null) { | ||
experimentKey = decision.experiment.key; | ||
} | ||
|
||
let variationKey = ''; | ||
if (variation) { | ||
variationKey = variation.key | ||
} |
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.
After upgrading TS we have access to some new language features that I believe could make this section more succinct: optional chaining and nullish coalescing. Check these out and let me know what you think.
@@ -486,7 +522,7 @@ export default class Optimizely { | |||
* then clear the existing experiment-to-variation mapping. | |||
* @return {boolean} A boolean value that indicates if the set completed successfully. | |||
*/ | |||
setForcedVariation(experimentKey: string, userId: string, variationKey: string | null): boolean { | |||
setForcedVariation(experimentKey: string, userId: string, variationKey: string): boolean { |
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 an unrelated fix, or does it matter to flag decisions?
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.
Let's keep it as it was, it should not matter to flag decisions. I updated DecisionService.prototype.setForcedVariation
comments to avoid confusion.
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 looks great! The changes in the Optimizely
class are so much cleaner 💯 .
Requesting changes for adding a few unit tests in the decision
module.
@@ -0,0 +1,44 @@ | |||
/** |
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.
Let's add some basic unit tests for this module. I think we should have some coverage for when experiment
or variation
are null
or undefined
.
@@ -0,0 +1,11 @@ | |||
import { LogTierV1EventProcessor, LocalStoragePendingEventsDispatcher } from '@optimizely/js-sdk-event-processor'; |
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.
import { LogTierV1EventProcessor, LocalStoragePendingEventsDispatcher } from '@optimizely/js-sdk-event-processor'; | |
/** | |
* Copyright 2020, Optimizely | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import { LogTierV1EventProcessor, LocalStoragePendingEventsDispatcher } from '@optimizely/js-sdk-event-processor'; |
@@ -297,7 +297,7 @@ export var getVariationKeyFromId = function(projectConfig, variationId) { | |||
*/ | |||
export var getVariationIdFromExperimentAndVariationKey = function(projectConfig, experimentKey, variationKey) { | |||
var experiment = projectConfig.experimentKeyMap[experimentKey]; | |||
if (experiment.variationKeyMap.hasOwnProperty(variationKey)) { | |||
if (variationKey !== '' && experiment.variationKeyMap.hasOwnProperty(variationKey)) { |
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 change really necessary? It seems like it would only matter in the case where variationKeyMap
has a ''
property, which I don't think will happen (we don't allow empty strings as variation keys).
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.
Good point. I will remove it.
@@ -97,7 +97,7 @@ declare module '@optimizely/optimizely-sdk' { | |||
userId: string, | |||
attributes?: UserAttributes | |||
): string | null; | |||
setForcedVariation(experimentKey: string, userId: string, variationKey: string | null): boolean; | |||
setForcedVariation(experimentKey: string, userId: string, variationKey: string): boolean; |
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 is a breaking API change - let's not do this in the current PR.
e2525d2
to
69c0133
Compare
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.
Please add an entry to CHANGELOG.md. Otherwise, LGTM.
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
sendFlagDecisions
is enabled.Test plan