Craft By Zen

Railroad semafor. Credits: Unsplash - Michał Franczak
Railroad semafor. Credits: Unsplash - Michał Franczak

6 min read

🔖programming   🔖flags

Flag management in practice

What is Feature Management?

A feature flag is a decision point in your code that can change the behavior of your application.

Temporary flags are often used to safely deploy changes to your application or to test new behaviors against old ones. After a new behavior is being used by 100% of your users, the flag is intended to be removed.

Traffic light showing a green light. Unsplash - Eliobed Suarez

Traffic light showing a green light. Unsplash - Eliobed Suarez

Permanent flags give you a way to control the behavior of your application at any time. You might use a permanent flag to create a kill-switch or to reveal functionality only to specific users.

Locked entrance. Unsplash - Muhammad Zaqy Al Fattah

Traffic light showing a green light. Unsplash - Eliobed Suarez

Feature Flags Are Context Sensitive

The code path token can change based on the context provided; for example, the user’s identity, the plan they’ve paid for, or any other data.

Feature Flags Are Deployment Agnostic

Feature flags can be used to control which users can see each change. This decouples the act of deploying from the act of releasing.

Use Cases for Flags

These are the ones advertised by LaunchDarkly. There are many more use cases, and they allow for customization.

What is LaunchDarkly?

A diagram showing the end-to-end connection between LaunchDarkly's flag delivery network and your application.

A diagram showing the end-to-end connection between LaunchDarkly’s flag delivery network and your application.

Source

How I use flags in practice

In our codebase, we have a custom React hook wrapped around the SDK that returns the flag value that we can use programmatically.

const [specificFlag] = useFeatureFlags([
  {
    flag: "specificFlagKey",
    defaultValue: false,
  },
]);

From here, we usually add conditional logic to toggle the flag logic to the target code. We can also use the same method to do the same on the server-side as well.

Adding User Context

LaunchDarkly uses context to target which flags should be on or off. The user’s context, known in LaunchDarkly as identity, must be used when initializing the application.

Anonymous Users

On initialization, a user session will be identified as an anonymous user. This is because in the initialization, the user’s session token (access token) has not been verified yet. Because we want to use flags for public users as well, i.e. those not logged into the app, we initialize the Provider before the token check.

An anonymous user has two attributes:

Authenticated Users

Once the user authenticates, and the application has retrieved the user context, we identifies the user using the ldClient.identify function. In this identify function, we pass along the following information about our user:

In addition, we pass along some custom fields that we can use to narrow down the user’s targeting. This includes their role and their organization, since our app is a multi-tenant.

If this user has already been added to LaunchDarkly, their flag profile will be returned.

If this user is new, LaunchDarkly will automatically create this user, create their flag profile, and be returned.

Logout

On logout, the application re-identifies the user using the ldClient.identify function. Since the application has a logout hook, we add a handler to identify the user to be an anonymous user again. This resets all flags to switch over for anonymous users.

When do we change our flags?

Deployments

There are different types of deployments:

Each of these can be implemented using feature flags.

Feature flags and blue/green deploys are complementary techniques. Although there are areas of overlap, each approach has distinct benefits, and the best strategy is to use both.

Testing

It isn’t necessary (or even possible) to test every combination of feature flags. Testing each variation of a flag in isolation (using default values for the other flags) is usually enough, unless there’s some known interaction between certain flags.

Here’s an example using jest and LaunchDarkly’s mock testing library.

import { mockFlags } from 'jest-launchdarkly-mock';

it('tests with the flag on' , () => {
  mockFlags({
    [FLAG_IN_QUESTION]: true,
  });
  // Write your test here
});

it('tests with the flag off' , () => {
  mockFlags({
    [FLAG_IN_QUESTION]: false,
  });
  // Write your test here
});

Flag Maintenance

Cleaning up flags aggressively is the key to preventing technical debt from building up. There’s no royal road to flag cleanup, but there are some processes that make it manageable.

A stale flag is a temporary flag that is no longer in use and has not been cleaned up. Too many stale flags are a form of technical debt and an antipattern that you should avoid.

At work, we follow a practice to do it prior to any major release. This is about every 3 to 4 months.

Questions you should be able to answer now

Learn More