-
Notifications
You must be signed in to change notification settings - Fork 1
feat: inspect format field to determine whether config is obfuscated #218
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
Changes from 4 commits
cb062eb
8aee608
e01f3b3
5ebe36e
f067c3b
04d8a43
0786d71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,8 +15,8 @@ import { LRUInMemoryAssignmentCache } from '../cache/lru-in-memory-assignment-ca | |
import { NonExpiringInMemoryAssignmentCache } from '../cache/non-expiring-in-memory-cache-assignment'; | ||
import { TLRUInMemoryAssignmentCache } from '../cache/tlru-in-memory-assignment-cache'; | ||
import { | ||
IConfigurationWire, | ||
ConfigurationWireV1, | ||
IConfigurationWire, | ||
IPrecomputedConfiguration, | ||
PrecomputedConfiguration, | ||
} from '../configuration'; | ||
|
@@ -27,6 +27,7 @@ import { | |
DEFAULT_POLL_CONFIG_REQUEST_RETRIES, | ||
DEFAULT_POLL_INTERVAL_MS, | ||
DEFAULT_REQUEST_TIMEOUT_MS, | ||
OBFUSCATED_FORMATS, | ||
} from '../constants'; | ||
import { decodeFlag } from '../decoding'; | ||
import { EppoValue } from '../eppo_value'; | ||
|
@@ -46,6 +47,7 @@ import { | |
BanditVariation, | ||
ConfigDetails, | ||
Flag, | ||
getFormatFromString, | ||
IPrecomputedBandit, | ||
ObfuscatedFlag, | ||
PrecomputedFlag, | ||
|
@@ -101,6 +103,12 @@ export type EppoClientParameters = { | |
banditVariationConfigurationStore?: IConfigurationStore<BanditVariation[]>; | ||
banditModelConfigurationStore?: IConfigurationStore<BanditParameters>; | ||
configurationRequestParameters?: FlagConfigurationRequestParameters; | ||
/** | ||
* Setting this value will have no side effects other than triggering a warning when the actual | ||
* configuration's obfuscated does not match the value set here. | ||
* | ||
* @deprecated obfuscation is determined by inspecting the `format` field of the UFC response. | ||
*/ | ||
typotter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
isObfuscated?: boolean; | ||
}; | ||
|
||
|
@@ -121,7 +129,9 @@ export default class EppoClient { | |
private assignmentCache?: AssignmentCache; | ||
// whether to suppress any errors and return default values instead | ||
private isGracefulFailureMode = true; | ||
private isObfuscated: boolean; | ||
private expectObfuscated: boolean; | ||
private obfuscationMismatchWarningIssued = false; | ||
private configObfuscatedCache?: boolean; | ||
private requestPoller?: IPoller; | ||
private readonly evaluator = new Evaluator(); | ||
|
||
|
@@ -138,7 +148,30 @@ export default class EppoClient { | |
this.banditVariationConfigurationStore = banditVariationConfigurationStore; | ||
this.banditModelConfigurationStore = banditModelConfigurationStore; | ||
this.configurationRequestParameters = configurationRequestParameters; | ||
this.isObfuscated = isObfuscated; | ||
this.expectObfuscated = isObfuscated; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🐛 This looks like it sets |
||
} | ||
|
||
private maybeWarnAboutObfuscationMismatch(configObfuscated: boolean) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason we develop elaborate warning for a deprecated flag?
|
||
// Don't warn again if we did on the last check. | ||
if (configObfuscated !== this.expectObfuscated && !this.obfuscationMismatchWarningIssued) { | ||
this.obfuscationMismatchWarningIssued = true; | ||
logger.warn( | ||
`[Eppo SDK] configuration obfuscation [${configObfuscated}] does not match expected [${this.expectObfuscated}]`, | ||
); | ||
} else if (configObfuscated === this.expectObfuscated) { | ||
// Reset the warning to false in case the client configuration (re-)enters a mismatched state. | ||
this.obfuscationMismatchWarningIssued = false; | ||
} | ||
} | ||
|
||
private isObfuscated() { | ||
if (this.configObfuscatedCache === undefined) { | ||
this.configObfuscatedCache = OBFUSCATED_FORMATS.includes( | ||
getFormatFromString(this.flagConfigurationStore.getFormat()), | ||
); | ||
} | ||
this.maybeWarnAboutObfuscationMismatch(this.configObfuscatedCache); | ||
return this.configObfuscatedCache; | ||
} | ||
|
||
setConfigurationRequestParameters( | ||
|
@@ -150,6 +183,7 @@ export default class EppoClient { | |
// noinspection JSUnusedGlobalSymbols | ||
setFlagConfigurationStore(flagConfigurationStore: IConfigurationStore<Flag | ObfuscatedFlag>) { | ||
this.flagConfigurationStore = flagConfigurationStore; | ||
this.configObfuscatedCache = undefined; | ||
} | ||
|
||
// noinspection JSUnusedGlobalSymbols | ||
|
@@ -188,8 +222,15 @@ export default class EppoClient { | |
} | ||
|
||
// noinspection JSUnusedGlobalSymbols | ||
/** | ||
* Setting this value will have no side effects other than triggering a warning when the actual | ||
* configuration's obfuscated does not match the value set here. | ||
* | ||
* @deprecated The client determines whether the configuration is obfuscated by inspection | ||
* @param isObfuscated | ||
typotter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
setIsObfuscated(isObfuscated: boolean) { | ||
this.isObfuscated = isObfuscated; | ||
this.expectObfuscated = isObfuscated; | ||
} | ||
|
||
async fetchFlagConfigurations() { | ||
|
@@ -236,6 +277,7 @@ export default class EppoClient { | |
|
||
const pollingCallback = async () => { | ||
if (await this.flagConfigurationStore.isExpired()) { | ||
this.configObfuscatedCache = undefined; | ||
return configurationRequestor.fetchAndStoreConfigurations(); | ||
} | ||
}; | ||
|
@@ -854,7 +896,7 @@ export default class EppoClient { | |
configDetails, | ||
subjectKey, | ||
subjectAttributes, | ||
this.isObfuscated, | ||
this.isObfuscated(), | ||
); | ||
|
||
// allocationKey is set along with variation when there is a result. this check appeases typescript below | ||
|
@@ -993,15 +1035,16 @@ export default class EppoClient { | |
); | ||
} | ||
|
||
const isObfuscated = this.isObfuscated(); | ||
const result = this.evaluator.evaluateFlag( | ||
flag, | ||
configDetails, | ||
subjectKey, | ||
subjectAttributes, | ||
this.isObfuscated, | ||
isObfuscated, | ||
expectedVariationType, | ||
); | ||
if (this.isObfuscated) { | ||
if (isObfuscated) { | ||
// flag.key is obfuscated, replace with requested flag key | ||
result.flagKey = flagKey; | ||
} | ||
|
@@ -1052,7 +1095,7 @@ export default class EppoClient { | |
} | ||
|
||
private getFlag(flagKey: string): Flag | null { | ||
return this.isObfuscated | ||
return this.isObfuscated() | ||
typotter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
? this.getObfuscatedFlag(flagKey) | ||
: this.flagConfigurationStore.get(flagKey); | ||
} | ||
|
@@ -1220,7 +1263,7 @@ export default class EppoClient { | |
|
||
private buildLoggerMetadata(): Record<string, unknown> { | ||
return { | ||
obfuscated: this.isObfuscated, | ||
obfuscated: this.isObfuscated(), | ||
sdkLanguage: 'javascript', | ||
sdkLibVersion: LIB_VERSION, | ||
}; | ||
|
Uh oh!
There was an error while loading. Please reload this page.