Skip to content

Feature flags

Nicolas Lorusso edited this page Jul 1, 2024 · 3 revisions

The client fetches the information configured at https://features.decentraland.systems/ This process occurs at the start of the application, before the plugins are initialized, so we ensure that we get the data as soon as possible.

How we fetch the data

We make a call IFeatureFlagsProvider.GetAsync(options, ct). This finally triggers an http request like:

curl --location 'https://feature-flags.decentraland.org/explorer.json' \
--header 'X-Address-Hash: 0x..usrAddr' \
--header 'X-Debug: false' \
--header 'referer: https://decentraland.org' \

We require to set the FeatureFlagOptions options param:

How to change options through program args

--feature-flags-url: represents the options.URL param to use different servers.

--feature-flags-hostname: represents the options.Hostname param as it is required to provide the configuration either for org, zone or local development.

An example if you want to set local development mode:

#!/bin/bash
./Decentraland.app --feature-flags-url https://feature-flags.decentraland.zone --feature-flags-hostname localhost

Another example if you want to set it on zone (dev):

#!/bin/bash
./Decentraland.app --feature-flags-url https://feature-flags.decentraland.zone --feature-flags-hostname https://decentraland.zone

How to check if a feature is enabled

The feature flag configuration is set into FeatureFlagsCache.

private readonly FeatureFlagsCache featureFlagsCache;

public MyClass(FeatureFlagsCache featureFlagsCache)
{
    this.featureFlagsCache = featureFlagsCache;
}

public void DoStuff()
{
    if (!featureFlagsCache.Configuration.IsEnabled("any-feature")) return;
    // Do your feature stuff
}

Variants

Refer to: https://gh.getunleash.io/reference/strategy-variants#what-are-strategy-variants

This is how you check if the variant is enabled:

if (!featureFlagsCache.Configuration.IsEnabled("any-feature", "my-variant")) return;

You can get the content in three different formats depending on how its configured: string, json or csv.

private readonly FeatureFlagsCache featureFlagsCache;

public MyClass(FeatureFlagsCache featureFlagsCache)
{
    this.featureFlagsCache = featureFlagsCache;
}

public void DoStringStuff()
{
    if (!featureFlagsCache.Configuration.IsEnabled("any-feature", "string-variant")) return;
    if (!featureFlagsCache.Configuration..TryGetTextPayload("any-feature", "string-variant", out string? str))

    // Do your feature stuff
}

public void DoCsvStuff()
{
    if (!featureFlagsCache.Configuration.IsEnabled("any-feature", "csv-variant")) return;
    if (!featureFlagsCache.Configuration.TryGetCsvPayload("user-allow-list", "csv-variant", out List<List<string>>? csv)) return;
    
    foreach (string value in csv[0])
    {
        // ...
    }
}

[Serializable]
struct MyJsonDto
{
    public string foo;
    public int bar;
}

public void DoJsonStuff()
{
    if (!featureFlagsCache.Configuration.IsEnabled("any-feature", "json-variant")) return;
    if (!featureFlagsCache.Configuration.TryGetCsvPayload("user-allow-list", "json-variant", out MyJsonDto? json)) return;
    
    // Do your feature stuff
}