Diff for "FeatureFlags"

Not logged in - Log In / Register

Differences between revisions 2 and 4 (spanning 2 versions)
Revision 2 as of 2011-02-15 07:26:03
Size: 2847
Editor: mbp
Comment:
Revision 4 as of 2011-02-15 08:08:59
Size: 5234
Editor: mbp
Comment:
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:

== Key points ==

 * Guard new potentially-dangerous or controversial features by a flag.
 * Make sure the documentation is clear enough to make sense to a LOSA in a high-pressure situation; '''don't assume''' they will be familiar with the detailed implementation of the feature.
Line 8: Line 13:
 * Scram switches (omg daily builds are killing us, make it stop)  * Scram switches (eg "omg daily builds are killing us, make it stop")
Line 20: Line 25:
For a list of available flags and scopes see https://launchpad.net/+feature-info

== Priority ==

Prority is exposed as an integer that gives a total order across all rules. The numerically highest priority wins. [[https://bugs.launchpad.net/launchpad/+bug/669942|For example]] with these rules

{{{
hard_timeout team:admins 1 18000
hard_timeout default 0 15000
}}}

the first rule has a higher priority (1 > 0). So that rule is evaluated first, and it will match for anyone in ~admins. If that doesn't match, the second is evaluated and it is always true. So admins get a 18s timeout, and everyone else 15s.
Line 23: Line 41:

Feature rules are loosely coupled to code changes: you can activate rules before the code they control is live.
Line 39: Line 59:
== Checking a feature flag == === Flag naming ===
Flags should be named as

 '''scope.feature.effect'''

where each of the parts is a legal Python name (so use underscores to join words, not dashes.)

The '''scope''' is the general area of Launchpad this relates to: eg 'code', 'librarian', ...

The '''feature''' is the particular thing that's being controlled, such as 'recipes' or 'render_time'.

The '''effect''' is typically 'enabled', 'visible', or 'timeout'. These should always be in the positive sense, not 'disabled'. If timeouts are given, they should be in seconds (decimals can be given in the value.)

=== Scope naming ===

Servers are matched using a simple regexp and for those that take parameters they are separated by a colon, eg {{{team:admins}}}.

There is no way at present to give a rule that checks multiple scopes or any other boolean conditions. You need to either choose one to match first, or add a new scope that matches just what you need, or extend the feature flag infrastructure to evaluate boolean expressions.

== Reading a feature flag ==
Line 47: Line 86:
If you introduce a new feature flag, as well as reading it from whereever is useful, you should also:

 * Add a section in {{{lib/lp/services/features/flags.py flag_info}}} describing the flag.
Line 48: Line 91:

Add a new class in {{{lib/lp/services/features/scopes.py}}} and insert it into {{{HANDLERS}}} in that file.

Feature Flags

FeatureFlags allow Launchpad's configuration to be changed while it's running, and for particular features or behaviours to be exposed to only a subset of users or requests.

Key points

  • Guard new potentially-dangerous or controversial features by a flag.
  • Make sure the documentation is clear enough to make sense to a LOSA in a high-pressure situation; don't assume they will be familiar with the detailed implementation of the feature.

Scenarios

  • Dark launches (aka embargoes: land code first, turn it on later)
  • Closed betas
  • Scram switches (eg "omg daily builds are killing us, make it stop")
  • Soft/slow launch (let just a few users use it and see what happens)
  • Site-wide notification
  • Show an 'alpha', 'beta' or 'new!' badge next to a UI control, then later turn it off without a new rollout
  • Show developer-oriented UI only to developers (eg the query count)
  • Control page timeouts (or other resource limits) either per page id, or per user group
  • Set resource limits (eg address space cap) for jobs.

Concepts

A feature flag has a string name, and has a dynamically-determined value within a particular context such as a web or api request. The value in that context depends on determining which scopes are relevant to the context, and what rules exist for that flag and scopes. The rules are totally ordered and the highest-prority rule determines the relevant value.

For a list of available flags and scopes see https://launchpad.net/+feature-info

Priority

Prority is exposed as an integer that gives a total order across all rules. The numerically highest priority wins. For example with these rules

hard_timeout team:admins 1 18000
hard_timeout default 0 15000

the first rule has a higher priority (1 > 0). So that rule is evaluated first, and it will match for anyone in ~admins. If that doesn't match, the second is evaluated and it is always true. So admins get a 18s timeout, and everyone else 15s.

Operations

A change to a flag in production counts as a production change: it is made by a LOSA on request from a squad lead, or other relevant manager. Ask in #launchpad-ops or #launchpad-dev.

Feature rules are loosely coupled to code changes: you can activate rules before the code they control is live.

Web interface

Debugging

A html comment at the bottom of rendered pages describes which features were looked up, and which scopes were consulted to make that decision. This doesn't include features that could be active but aren't relevant to the page, or scopes that may be active but aren't relevant to deciding the value of the features.

Performance

Feature flags are designed and intended to be fast enough that they can be used as much as is useful within reason. The result of a flag and of a scope is checked at most once per request.

Naming conventions

Flag naming

Flags should be named as

  • scope.feature.effect

where each of the parts is a legal Python name (so use underscores to join words, not dashes.)

The scope is the general area of Launchpad this relates to: eg 'code', 'librarian', ...

The feature is the particular thing that's being controlled, such as 'recipes' or 'render_time'.

The effect is typically 'enabled', 'visible', or 'timeout'. These should always be in the positive sense, not 'disabled'. If timeouts are given, they should be in seconds (decimals can be given in the value.)

Scope naming

Servers are matched using a simple regexp and for those that take parameters they are separated by a colon, eg team:admins.

There is no way at present to give a rule that checks multiple scopes or any other boolean conditions. You need to either choose one to match first, or add a new scope that matches just what you need, or extend the feature flag infrastructure to evaluate boolean expressions.

Reading a feature flag

  • Python code: features.getFeatureFlag(name) => value

  • TAL code: <div tal:condition="features/name">hello world!"</div>

Adding a new feature flag

If you introduce a new feature flag, as well as reading it from whereever is useful, you should also:

  • Add a section in lib/lp/services/features/flags.py flag_info describing the flag.

Adding a new scope controller

Add a new class in lib/lp/services/features/scopes.py and insert it into HANDLERS in that file.

See also

FeatureFlags (last edited 2020-08-24 16:13:59 by cjwatson)