Merge lp:~mbp/launchpad/flags into lp:launchpad/db-devel
| Status: | Merged |
|---|---|
| Approved by: | Robert Collins on 2010-07-22 |
| Approved revision: | no longer in the source branch. |
| Merged at revision: | 9573 |
| Proposed branch: | lp:~mbp/launchpad/flags |
| Merge into: | lp:launchpad/db-devel |
| Diff against target: |
300 lines (+264/-0) 7 files modified
lib/lp/services/features/__init__.py (+10/-0) lib/lp/services/features/flags.py (+85/-0) lib/lp/services/features/model.py (+42/-0) lib/lp/services/features/scopes.py (+5/-0) lib/lp/services/features/tests/__init__.py (+2/-0) lib/lp/services/features/tests/test_db_settings.py (+25/-0) lib/lp/services/features/tests/test_flags.py (+95/-0) |
| To merge this branch: | bzr merge lp:~mbp/launchpad/flags |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Robert Collins (community) | 2010-07-21 | Approve on 2010-07-22 | |
|
Review via email:
|
|||
Commit Message
Add FeatureController to read feature flags from the db
Description of the Change
Second instalment of https:/
This adds a class that tells you about active features in a particular scope. It would be usable as is but I will do more to automatically give you the right context in a web app request, etc.
| Martin Pool (mbp) wrote : | # |
Incremental diff:
* facade loads everything at construction time
* remove write facade methods
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -6,21 +6,16 @@
__metaclass__ = type
-from lp.services.
+from lp.services.
+ getFeatureStore,
+ FeatureFlag,
+ )
from storm.locals import (
Desc,
)
-# Intended performance: when this object is first constructed, it will read
-# the whole current feature flags from the database. This will take a few ms.
-# The controller is then supposed to be held in a thread-local for the
-# duration of the request. The scopes can be changed over the lifetime of the
-# controller, because we might not know enough to determine all the active
-# scopes when the object's first created. This isn't validated to work yet.
-
-
class FeatureControll
"""A FeatureController tells application code what features are active.
@@ -30,18 +25,21 @@
of the current web request, or the user for whom a job is being run, or
something similar.
- This presents a higher-level facade that is independent of how the flags
- are stored. At the moment they are stored in the database but callers
- shouldn't need to know about that: they could go into memcachedb or
- elsewhere in future.
+ FeatureController presents a high level interface for application code to
+ query flag values, without it needing to know that they are stored in the database.
At this level flag names and scope names are presented as strings for
easier use in Python code, though the values remain unicode. They
should always be ascii like Python identifiers.
- One instance of this should be constructed for the lifetime of code that
- has consistent configuration values. For instance there will be one per web
- app request.
+ One instance of FeatureController should be constructed for the lifetime
+ of code that has consistent configuration values. For instance there will
+ be one per web app request.
+
+ Intended performance: when this object is first constructed, it will read
+ the whole current feature flags from the database. This will take a few ms.
+ The controller is then supposed to be held in a thread-local for the
+ duration of the request.
See <https:/
"""
@@ -49,34 +47,33 @@
def __init__(self, scopes):
"""
- self._store = model.getFeatur
- self.scopes = self._preenScop
+ self._store = getFeatureStore()
+ self._scopes = self._preenScop
+ self._cached_flags = self._queryAllF
- def setScopes(self, scopes):
- self.scopes = self._preenScop
+ def getScopes(self):
+ return frozenset(
def getFlag(self, flag_name):
- rs = (self._store
- .find(model.
- mod...
| Martin Pool (mbp) wrote : | # |
ec2 disappeared into thin air, perhaps because of smtp setup problems. Would someone please submit this on my behalf?

I think referencing the LEP in the docstring is ok but not a substitute for including the docs in the tree - better to include the information in the module so that people don't need a web connection to understand whats going on.
I like the intended performance notes - please put them in the docstring so the API docs will show them.
I would perhaps say '
53 + This presents a higher-level interface over the storm model objects,
54 + oriented only towards readers.
55 +
56 + At this level flag names and scope names are presented as strings for
57 + easier use in Python code, though the values remain unicode. They
58 + should always be ascii like Python identifiers.
'
As
This presents an interface optimised for use in code making conditional choices based on the feature flags. At this level ....
This -
165 + # the Launchpad Collection knows how to find a good store to start from,
166 +
is a bit weird to mention.
169 === added file 'lib/lp/ services/ features/ scopes. py' services/ features/ scopes. py 1970-01-01 00:00:00 +0000 services/ features/ scopes. py 2010-07-21 21:16:48 +0000
170 --- lib/lp/
171 +++ lib/lp/
172 @@ -0,0 +1,5 @@
173 +# Copyright 2010 Canonical Ltd. This software is licensed under the
174 +# GNU Affero General Public License version 3 (see the file LICENSE).
175 +
176 +"""Look up current feature flags.
177 +"""
This seems unused - you might want to trim it for now.
179 === added directory 'lib/lp/ services/ features/ tests' services/ features/ tests/_ _init__ .py' services/ features/ tests/_ _init__ .py 1970-01-01 00:00:00 +0000 services/ features/ tests/_ _init__ .py 2010-07-21 21:16:48 +0000
180 === added file 'lib/lp/
181 --- lib/lp/
182 +++ lib/lp/
183 @@ -0,0 +1,4 @@
184 +# Copyright 2010 Canonical Ltd. This software is licensed under the
185 +# GNU Affero General Public License version 3 (see the file LICENSE).
186 +
187 +pass
The pass isn't needed :)
189 === added file 'lib/lp/ services/ features/ tests/test_ db_settings. py' services/ features/ tests/test_ db_settings. py 1970-01-01 00:00:00 +0000 services/ features/ tests/test_ db_settings. py 2010-07-21 21:16:48 +0000
190 --- lib/lp/
191 +++ lib/lp/
192 @@ -0,0 +1,26 @@
193 +# Copyright 2010 Canonical Ltd. This software is licensed under the
194 +# GNU Affero General Public License version 3 (see the file LICENSE).
195 +
196 +"""Tests for feature settings coming from the database"""
197 +
198 +
199 +from __future__ import with_statement
200 +__metaclass__ = type
201 +
202 +import testtools
Launchpad has a TestCase of its own you should use.
204 +from canonical.testing import layers features. model import ( ection, l(testtools. TestCase) : DatabaseFunctio nalLayer tyCollection( self): ection( ) (coll.select( ).is_empty( ))
205 +from lp.services.
206 + FeatureFlag,
207 + FeatureFlagColl
208 + )
209 +
210 +
211 +class TestFeatureMode
212 +
213 + layer = layers.
214 +
215 + def test_defaultEmp
216 + # there are no settings in the sampledata
217 + coll = FeatureFlagColl
218 + self.assertTrue
I'd make that statement stronger: there should be no settings...
220 === added file 'lib/lp/ services/ features/ tests/test_ flags.py' services/ fea...
221 --- lib/lp/