From f2498e9b9c22693ac6af7e3dc2c5b98280c2ec0f Mon Sep 17 00:00:00 2001 From: Samuel Holmes Date: Wed, 25 Oct 2023 10:51:05 -0700 Subject: [PATCH 1/2] Fix generateExperimentConfigVal The logic was incorrect for checking each bucket of probabilities for 3+ variants --- CHANGELOG.md | 1 + src/experimentConfig.ts | 35 +++++++++++++++++++++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c87b51c635d..8e1cbc2d460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - changed: Change FlipInput styling to make the edit functionality more obvious - changed: Enable max spend for Filecoin - changed: Move asset-specific settings into their own settings page +- changed: Experiment config probability distribution support percentage based values - removed: Moonpay sell via ACH - removed: Banxa buy via Pix diff --git a/src/experimentConfig.ts b/src/experimentConfig.ts index 49b656cb8fb..c51f9052c2c 100644 --- a/src/experimentConfig.ts +++ b/src/experimentConfig.ts @@ -26,14 +26,13 @@ const DEFAULT_EXPERIMENT_CONFIG: ExperimentConfig = { const experimentConfigDisklet = makeReactNativeDisklet() -// The probability (0-1) of a feature config being set to the first value(s): -// the configuration that differs from the default feature configuration. +// The probability of an experiment config feature being set for a given key const experimentDistribution = { - swipeLastUsp: [0.5], - createAccountType: [0.5], - legacyLanding: [0], - createAccountText: [0.33, 0.33], - signupCaptcha: [0.5] + swipeLastUsp: [50, 50], + createAccountType: [50, 50], + legacyLanding: [100], + createAccountText: [33.33, 33.33, 33.33], + signupCaptcha: [50, 50] } /** @@ -41,19 +40,31 @@ const experimentDistribution = { * determine which variant gets used. */ const generateExperimentConfigVal = (key: keyof typeof experimentDistribution, configVals: T[]): T => { - const variantProbability = experimentDistribution[key] + const variantNominations = experimentDistribution[key] - if (variantProbability.length !== configVals.length - 1) { + if (variantNominations.length !== configVals.length) { console.error(`Misconfigured experimentDistribution for: '${key}'`) } else { + // Distribute the probability of each config value + const variantDenomination = variantNominations.reduce((sum, probability) => sum + probability, 0) + if (variantDenomination === 0) { + throw new Error(`Config values for '${key}' do not add up to 100%`) + } else if (variantDenomination > 101 || variantDenomination < 99) { + console.warn(`Config values for '${key}' do not add up to 100% +/- 1%`) + } + const distributedProbabilities = variantNominations.map(variantNomination => variantNomination / variantDenomination) + // Generate a random number between 0 and 1 const random = Math.random() // Check which index the random number falls into and return the configVal: let lowerBound = 0 - for (let i = 0; i < variantProbability.length; i++) { - if (random >= lowerBound && random < variantProbability[i]) return configVals[i] - lowerBound += variantProbability[i] + let upperBound = distributedProbabilities[0] + for (let i = 0; i < distributedProbabilities.length; i++) { + if (random >= lowerBound && random < upperBound) return configVals[i] + + lowerBound = upperBound + upperBound += distributedProbabilities[i] } } From ad8fdb9b4a19ce657157ce0402d33d44c802630d Mon Sep 17 00:00:00 2001 From: Jon Tzeng Date: Fri, 20 Oct 2023 15:07:55 -0700 Subject: [PATCH 2/2] Fix experiment config disk copy management If new values were added to the experiment config, those new values weren't getting stored and the client was regenerating every time --- CHANGELOG.md | 1 + src/experimentConfig.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e1cbc2d460..a4ba5ce8e71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - changed: Enable max spend for Filecoin - changed: Move asset-specific settings into their own settings page - changed: Experiment config probability distribution support percentage based values +- fixed: Write updated experiment configs to disk - removed: Moonpay sell via ACH - removed: Banxa buy via Pix diff --git a/src/experimentConfig.ts b/src/experimentConfig.ts index c51f9052c2c..b9657dbaed5 100644 --- a/src/experimentConfig.ts +++ b/src/experimentConfig.ts @@ -92,17 +92,19 @@ const asExperimentConfig: Cleaner = asObject({ * This config value is available through the module's getter functions. */ const experimentConfigPromise: Promise = (async (): Promise => { + let currentConfig: ExperimentConfig try { const experimentConfigJson = await experimentConfigDisklet.getText(LOCAL_EXPERIMENT_CONFIG) - return asExperimentConfig(JSON.parse(experimentConfigJson)) + currentConfig = asExperimentConfig(JSON.parse(experimentConfigJson)) } catch (err) { - console.debug('Experiment config not found/out of date. Regenerating...') + console.log('Experiment config not found/out of date. Regenerating...') // Not found or incompatible. Re-generate with random values according to // the defined distribution. - const generatedExperimentConfig = asExperimentConfig({}) - await experimentConfigDisklet.setText(LOCAL_EXPERIMENT_CONFIG, JSON.stringify(generatedExperimentConfig)) - return generatedExperimentConfig + currentConfig = asExperimentConfig({}) } + + await experimentConfigDisklet.setText(LOCAL_EXPERIMENT_CONFIG, JSON.stringify(currentConfig)) + return currentConfig })() /** @@ -117,7 +119,7 @@ export const getExperimentConfig = async (): Promise => { if (isMaestro()) return DEFAULT_EXPERIMENT_CONFIG // Test with forced defaults else if (ENV.EXPERIMENT_CONFIG_OVERRIDE != null && Object.keys(ENV.EXPERIMENT_CONFIG_OVERRIDE).length > 0) { try { - console.debug('exp cfg override') + console.log('ENV.EXPERIMENT_CONFIG_OVERRIDE set') return asExperimentConfig(ENV.EXPERIMENT_CONFIG_OVERRIDE) } catch (err) { console.error('Error applying ENV.EXPERIMENT_CONFIG_OVERRIDE: ', String(err))