Skip to content
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: properly handle flag resolver variants #3808

Merged
merged 3 commits into from
May 18, 2023
Merged

Conversation

nunogois
Copy link
Member

@nunogois nunogois commented May 18, 2023

Variants were not being properly handled in the flag-resolver: The fact that the default value of the variant is not falsy made it so we never asked the external flag resolver for the value.

This also moves the logic from Variant | undefined to Variant where we use the getDefaultVariant() helper method to return us a default variant.

@vercel
Copy link

vercel bot commented May 18, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
unleash-monorepo-frontend ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 18, 2023 3:17pm
1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
unleash-docs ⬜️ Ignored (Inspect) May 18, 2023 3:17pm

@@ -18,7 +18,8 @@ export interface Variant {
export const getVariantValue = <T = string>(
variant: Variant | undefined
): T | undefined => {
if (variant?.payload !== undefined) {
if (variant?.enabled) {
if (!variant.payload) return variant.name as T;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this correct? Is the value of the variant the name if the payload is not defined?

Copy link
Member Author

Choose a reason for hiding this comment

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

That was the intention, yes. In case you don't specify a payload, the only thing you can use to identify the variant and runtime control, effectively its value in the perspective of this helper, turns out to be its name.

Copy link
Member Author

@nunogois nunogois May 18, 2023

Choose a reason for hiding this comment

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

In case it helps visualizing what I mean in our UI:
image

We didn't specify a payload, so the variant name acts as our value.
This means that we could easily do something like:

const variant = getVariantValue(uiConfig.flags.ourVariant)

if (variant === 'variant-A') {
  // Do cool thing
}

if (typeof flags[flagName] === 'boolean') {
const flag = flags[flagName];
if (typeof flag === 'boolean') {
if (!flag) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't this prevent the flag to be evaluated again? If it's turned true once, it seems you can't disable it because you'll skip the isEnabled evaluation

Copy link
Member Author

@nunogois nunogois May 18, 2023

Choose a reason for hiding this comment

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

If I understood the original reasoning, our flag here is the default value we get from either experimental or server-dev, not the current state of the flag. I.e. the initial value.

What we're saying here is, unless one those two places above override the flag by setting it as something truthy (e.g. env variable), we want to fetch it from the external resolver.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I saw it now, and flags is a local variable of this method

} else {
}
} else {
if (!flag?.enabled) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we still resolve getVariant even if it's not enabled? It would give us the default variant

Copy link
Member Author

Choose a reason for hiding this comment

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

Same as above, if the initial value is falsy (not overridden be either experimental or server-dev to be truthy), we want to see what our external resolver has to say about it.

It may not be the default variant in this case. We may have a falsy initial value, but our external resolver (e.g. Unleash hosted) saying that this flag should be enabled, etc.

Copy link
Contributor

@gastonfournier gastonfournier left a comment

Choose a reason for hiding this comment

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

LG!

Copy link
Contributor

@gastonfournier gastonfournier left a comment

Choose a reason for hiding this comment

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

LG!

@nunogois nunogois merged commit 4adc977 into main May 18, 2023
16 checks passed
@nunogois nunogois deleted the fix-flag-resolver-variants branch May 18, 2023 16:04
nunogois added a commit that referenced this pull request Jan 24, 2024
https://linear.app/unleash/issue/2-1880/fix-flag-resolver-getvariant-behavior

Fixes the flag resolver `getVariant` behavior when there's a variant
object set in `experimental` - The flag resolver should call the
external resolver `getVariant` when not overridden to be true, even if
set as variant object in `experimental`.

Related: #3808
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

2 participants