Skip to content
This repository has been archived by the owner on Aug 29, 2020. It is now read-only.

Commit

Permalink
improve readability through emphasis
Browse files Browse the repository at this point in the history
  • Loading branch information
mistermicheels committed Mar 9, 2019
1 parent 10c83cd commit dc70b11
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 23 deletions.
10 changes: 5 additions & 5 deletions _posts/2019-02-16-Trunk-based-development.md
Expand Up @@ -152,11 +152,11 @@ Application strangulation is very similar to Branch by Abstraction, but it works

## Some good practices when applying Trunk Based Development

- Quick reviews: Developers try to get their code reviewed as soon as possible.
- Chasing HEAD: Developers try to stay up to date with changes to the trunk.
- Shared nothing: Developers run the build locally before pushing their code, typically including integration and functional tests talking to real databases etc. This means individual developers must be able to run the application and all its dependencies locally, without depending on resources shared with others.
- Facilitating commits: Developers sometimes chop up their work into multiple smaller commits in order to make their changes easier for their teammates to adjust to. For example, when building a feature entails introducing a new dependency, this dependency could be introduced separately through a new commit that the developer explicitly notifies the team of.
- Thin Vertical Slices: Stories or tasks from the backlog can ideally be implemented completely by a single developer or pair of developers in a short amount of time and small number of commits. They cut across the whole stack and they do not need to be passed around between developers with specialized knowledge in order to get completed.
- *Quick reviews*: Developers try to get their code reviewed as soon as possible.
- *Chasing HEAD*: Developers try to stay up to date with changes to the trunk.
- *Shared nothing*: Developers run the build locally before pushing their code, typically including integration and functional tests talking to real databases etc. This means individual developers must be able to run the application and all its dependencies locally, without depending on resources shared with others.
- *Facilitating commits*: Developers sometimes chop up their work into multiple smaller commits in order to make their changes easier for their teammates to adjust to. For example, when building a feature entails introducing a new dependency, this dependency could be introduced separately through a new commit that the developer explicitly notifies the team of.
- *Thin Vertical Slices*: Stories or tasks from the backlog can ideally be implemented completely by a single developer or pair of developers in a short amount of time and small number of commits. They cut across the whole stack and they do not need to be passed around between developers with specialized knowledge in order to get completed.

## Resources

Expand Down
36 changes: 18 additions & 18 deletions _posts/2019-03-02-Feature-flags.md
Expand Up @@ -35,12 +35,12 @@ When using a toggle router, the state of the flag could potentially be changed f
## Feature flag use cases
- Decoupling deployment from release: Feature flags allow a team to deploy a new version of the codebase, containing some code for an unfinished new feature, without that new feature affecting the users yet. This is particularly useful when practicing [Trunk Based Development]({% post_url 2019-02-16-Trunk-based-development %}).
- Incremental releasing: Using feature flags that are toggled on or off dynamically based on the user, it is possible to turn a feature on for a small percentage of the users and monitor its effect before rolling out the feature to all users. This is called a *canary release* or *percentage deploy*. It is essentially a way to test in production, with real user behavior and real data, while limiting risk. There is also a technique called *ring deploys*. The mechanism is the same, but the difference is that the users are not selected randomly but are rather chosen based on risk. You could start with internal users, then add a very small *canary group* of randomly selected real users, then include registered beta testers, etc.
- A/B testing: When deciding between two approaches (or whether or not to change something or keep it), you can use feature flags to enable approach A for a group of users and approach B for another group of users. Monitoring of the different groups should then help you decide which approach to choose.
- Kill switches: Feature flags can be used to temporarily switch off resource-heavy features when the system is under heavy load (think of an e-commerce website on Black Friday).
- Plan management: Some services use feature flags to offer a different feature set to different users based on how expensive their subscription is.
- Incremental infrastructure migrations: Feature flags can be used to perform infrastructure migrations on production in small steps (each toggled by a flag) that can be rolled back if needed by turning off the flag. After each step, the team can verify that the system still works correctly.
- *Decoupling deployment from release*: Feature flags allow a team to deploy a new version of the codebase, containing some code for an unfinished new feature, without that new feature affecting the users yet. This is particularly useful when practicing [Trunk Based Development]({% post_url 2019-02-16-Trunk-based-development %}).
- *Incremental releasing*: Using feature flags that are toggled on or off dynamically based on the user, it is possible to turn a feature on for a small percentage of the users and monitor its effect before rolling out the feature to all users. This is called a *canary release* or *percentage deploy*. It is essentially a way to test in production, with real user behavior and real data, while limiting risk. There is also a technique called *ring deploys*. The mechanism is the same, but the difference is that the users are not selected randomly but are rather chosen based on risk. You could start with internal users, then add a very small *canary group* of randomly selected real users, then include registered beta testers, etc.
- *A/B testing*: When deciding between two approaches (or whether or not to change something or keep it), you can use feature flags to enable approach A for a group of users and approach B for another group of users. Monitoring of the different groups should then help you decide which approach to choose.
- *Kill switches*: Feature flags can be used to temporarily switch off resource-heavy features when the system is under heavy load (think of an e-commerce website on Black Friday).
- *Plan management*: Some services use feature flags to offer a different feature set to different users based on how expensive their subscription is.
- *Incremental infrastructure migrations*: Feature flags can be used to perform infrastructure migrations on production in small steps (each toggled by a flag) that can be rolled back if needed by turning off the flag. After each step, the team can verify that the system still works correctly.
## Categorizing feature flags
Expand Down Expand Up @@ -121,11 +121,11 @@ Sometimes, it makes sense to put toggle points in the core of the system, close
There are several ways of managing feature flag configuration, some allowing for more flexibility than others. That flexibility is especially important for feature flags that need to change configuration often or need to be able to change their configuration instantly (for example kill switches). Do note that the fact that a fag is dynamic, in the sense that it has different values for different users, does not necessarily mean that the flag's configuration will change often. For example, the rules for which users see a plan management feature flag as "on" could even be hard-coded.
An overview of some approaches for managing feature flag configuration:
- Hard-coded or baked in: In this case, the feature flag configuration is stored in the actual code. Some teams may also set the value of the flag as part of the build process. This approach can work for flags guarding unfinished features, where we never want those features to be enabled in production.
- Command line variables, environment variables or config files: This approach could be useful the value of a flag should be able to change without having to rebuild the application. However, a restart is often needed in order to use the new configuration. With this approach, it may also be challenging to keep flag configuration consistent across multiple servers or processes.
- App database: Storing feature flag configuration in the app database means that there is a single source of truth that is potentially shared across multiple servers. This approach typically also allows the configuration to be changed at runtime, often through some kind of admin UI. There may be some limitations imposed on which users can change the configuration for certain flags.
- Feature management system: When the (typically home-grown) solution of putting configuration in the app database starts feeling a bit limited or brittle, teams often upgrade to a dedicated system specifically aimed at managing feature flag configuration. They provide a UI for managing the configuration, including limitations on who can change what. There may even be an audit log tracking when changes were made and by who. Often, feature management systems provide mechanisms to ensure that any changes made to the configuration are propagated quickly to all systems that need to know about them. They may also provide tools that help with integrating knowledge about flag configuration and certain application metrics, helping to analyze the effect of turning a certain flag on or off.
- Configuration overrides: In some cases, it makes sense to allow feature flag configuration to be overridden, for example by passing a special cookie, query parameter or HTTP header.
- *Hard-coded or baked in*: In this case, the feature flag configuration is stored in the actual code. Some teams may also set the value of the flag as part of the build process. This approach can work for flags guarding unfinished features, where we never want those features to be enabled in production.
- *Command line variables, environment variables or config files*: This approach could be useful the value of a flag should be able to change without having to rebuild the application. However, a restart is often needed in order to use the new configuration. With this approach, it may also be challenging to keep flag configuration consistent across multiple servers or processes.
- *App database*: Storing feature flag configuration in the app database means that there is a single source of truth that is potentially shared across multiple servers. This approach typically also allows the configuration to be changed at runtime, often through some kind of admin UI. There may be some limitations imposed on which users can change the configuration for certain flags.
- *Feature management system*: When the (typically home-grown) solution of putting configuration in the app database starts feeling a bit limited or brittle, teams often upgrade to a dedicated system specifically aimed at managing feature flag configuration. They provide a UI for managing the configuration, including limitations on who can change what. There may even be an audit log tracking when changes were made and by who. Often, feature management systems provide mechanisms to ensure that any changes made to the configuration are propagated quickly to all systems that need to know about them. They may also provide tools that help with integrating knowledge about flag configuration and certain application metrics, helping to analyze the effect of turning a certain flag on or off.
- *Configuration overrides*: In some cases, it makes sense to allow feature flag configuration to be overridden, for example by passing a special cookie, query parameter or HTTP header.
Whatever approach to configuration you choose, try to keep a clear separation between feature flag configuration and other kinds of configuration. Additionally, try to include some documentation or metadata (owner, purpose, ...) with the feature flag configuration if your approach allows it.
Expand All @@ -148,9 +148,9 @@ A pragmatic approach to testing could be the following:
## Database changes using the Expand-Contract pattern
Sometimes, changes in your code require changes to the structure of the data in the database. In a system without feature flags, one of these simple approaches could suffice:
- Code-first change: First deploy the new code, which is compatible with both the old and new database structure, then change the database
- Database-first change: Start by changing the database in a way which is compatible with both the old and new code, then deploy the new code
- Big bang: Take the system offline, change both the code and the database structure, then start the system again
- *Code-first change*: First deploy the new code, which is compatible with both the old and new database structure, then change the database
- *Database-first change*: Start by changing the database in a way which is compatible with both the old and new code, then deploy the new code
- *Big bang*: Take the system offline, change both the code and the database structure, then start the system again
If the changes are toggled through a feature flag, things become a bit more challenging. The flag may change state multiple times, both from "off" to "on" and from "on" to "off". One pattern for handling this situation is called *Expand-Contract migration*. The idea is that the database structure will first be expanded in order to support both states of the flag. Then, if the flag is removed, we contract the structure of the database by removing what is not needed anymore. This pattern could also be useful for making non-flagged changes in an incremental way without creating downtimes.
Expand All @@ -174,10 +174,10 @@ Some feature management systems can help with the detection of obsolete flags by
## General best practices
- Clear scope: The name of a flag should indicate what part of the system it affects, what the purpose of the feature it and ideally also at which layer the feature sits. An example naming convention is `section-purpose-layer`.
- Maintain consistency: Whenever possible, try to present the user with a consistent experience. This means consistency in which flags are turned on for the user. When doing percentage deploys and increasing the percentage, make sure that users for which the feature flag was previously in the "on" state still have the flag turned on. In some systems (like e-commerce applications), consistency becomes a bit more challenging because users start using the application before logging in. In that case, it may make sense to store a cookie with a visitor ID, use the visitor ID to determine which features are turned on for the user, and keep using that same visitor ID after the user has logged in.
- Server-side decisions: Try to keep decisions regarding whether or not a feature is enabled on the server side. This makes it a lot easier to manage feature flag states and keep them up to date. It also prevents tech-savvy users from playing with flag state themselves.
- Integrate monitoring with feature flagging: Feature flags can have an effect on business metrics like conversion rates, but also on technical metrics like CPU use. Take care to make sure that you can link changes in these metrics to changes in feature flags so you can properly analyze the effect of a flag. It may make sense to store some feature flag information with analytics events.
- *Clear scope*: The name of a flag should indicate what part of the system it affects, what the purpose of the feature it and ideally also at which layer the feature sits. An example naming convention is `section-purpose-layer`.
- *Maintain consistency*: Whenever possible, try to present the user with a consistent experience. This means consistency in which flags are turned on for the user. When doing percentage deploys and increasing the percentage, make sure that users for which the feature flag was previously in the "on" state still have the flag turned on. In some systems (like e-commerce applications), consistency becomes a bit more challenging because users start using the application before logging in. In that case, it may make sense to store a cookie with a visitor ID, use the visitor ID to determine which features are turned on for the user, and keep using that same visitor ID after the user has logged in.
- *Server-side decisions*: Try to keep decisions regarding whether or not a feature is enabled on the server side. This makes it a lot easier to manage feature flag states and keep them up to date. It also prevents tech-savvy users from playing with flag state themselves.
- *Integrate monitoring with feature flagging*: Feature flags can have an effect on business metrics like conversion rates, but also on technical metrics like CPU use. Take care to make sure that you can link changes in these metrics to changes in feature flags so you can properly analyze the effect of a flag. It may make sense to store some feature flag information with analytics events.
## Resources
Expand Down

0 comments on commit dc70b11

Please sign in to comment.