Index: appengine/auth_service/config.py |
diff --git a/appengine/auth_service/config.py b/appengine/auth_service/config.py |
index d387f205813ddb0c448feca8cb96edc162342e7f..f07b352cd7ab1083c2d445a6e6e94185fccf6a0b 100644 |
--- a/appengine/auth_service/config.py |
+++ b/appengine/auth_service/config.py |
@@ -34,7 +34,6 @@ from components import utils |
from components.auth import ipaddr |
from components.auth import model |
from components.config import validation |
-from components.config import validation_context |
from proto import config_pb2 |
import importer |
@@ -68,10 +67,17 @@ def get_remote_url(): |
return None |
-def get_config_revision(path): |
+def get_revisions(): |
+ """Returns a mapping {config file name => Revision instance or None}.""" |
+ futures = {p: _get_config_revision_async(p) for p in _CONFIG_SCHEMAS} |
+ return {p: f.get_result() for p, f in futures.iteritems()} |
+ |
+ |
+def _get_config_revision_async(path): |
"""Returns tuple with info about last imported config revision.""" |
+ assert path in _CONFIG_SCHEMAS, path |
schema = _CONFIG_SCHEMAS.get(path) |
- return schema['revision_getter']() if schema else None |
+ return schema['revision_getter']() |
@utils.cache_with_expiration(expiration_sec=60) |
@@ -115,7 +121,7 @@ def refetch_config(force=False): |
dirty_in_authdb = {} |
for path, (new_rev, conf) in sorted(configs.iteritems()): |
assert path in _CONFIG_SCHEMAS, path |
- cur_rev = get_config_revision(path) |
+ cur_rev = _get_config_revision_async(path).get_result() |
if cur_rev != new_rev or force: |
if _CONFIG_SCHEMAS[path]['use_authdb_transaction']: |
dirty_in_authdb[path] = (new_rev, conf) |
@@ -193,10 +199,11 @@ class _AuthServiceConfig(ndb.Model): |
url = ndb.StringProperty(indexed=False) |
-def _get_service_config_rev(cfg_name): |
+@ndb.tasklet |
+def _get_service_config_rev_async(cfg_name): |
"""Returns last processed Revision of given config.""" |
- e = _AuthServiceConfig.get_by_id(cfg_name) |
- return Revision(e.revision, e.url) if e else None |
+ e = yield _AuthServiceConfig.get_by_id_async(cfg_name) |
+ raise ndb.Return(Revision(e.revision, e.url) if e else None) |
def _get_service_config(cfg_name): |
@@ -222,13 +229,14 @@ def _update_service_config(cfg_name, rev, conf): |
### Group importer config implementation details. |
-def _get_imports_config_revision(): |
+@ndb.tasklet |
+def _get_imports_config_revision_async(): |
"""Returns Revision of last processed imports.cfg config.""" |
- e = importer.config_key().get() |
+ e = yield importer.config_key().get_async() |
if not e or not isinstance(e.config_revision, dict): |
- return None |
+ raise ndb.Return(None) |
desc = e.config_revision |
- return Revision(desc.get('rev'), desc.get('url')) |
+ raise ndb.Return(Revision(desc.get('rev'), desc.get('url'))) |
def _update_imports_config(rev, conf): |
@@ -255,15 +263,16 @@ def _imported_config_revisions_key(): |
return ndb.Key(_ImportedConfigRevisions, 'self', parent=model.root_key()) |
-def _get_authdb_config_rev(path): |
+@ndb.tasklet |
+def _get_authdb_config_rev_async(path): |
"""Returns Revision of last processed config given its name.""" |
- mapping = _imported_config_revisions_key().get() |
+ mapping = yield _imported_config_revisions_key().get_async() |
if not mapping or not isinstance(mapping.revisions, dict): |
- return None |
+ raise ndb.Return(None) |
desc = mapping.revisions.get(path) |
if not isinstance(desc, dict): |
- return None |
- return Revision(desc.get('rev'), desc.get('url')) |
+ raise ndb.Return(None) |
+ raise ndb.Return(Revision(desc.get('rev'), desc.get('url'))) |
@datastore_utils.transactional |
@@ -470,7 +479,7 @@ def _update_oauth_config(rev, conf): |
# Config file name -> { |
# 'proto_class': protobuf class of the config or None to keep it as text, |
-# 'revision_getter': lambda: <latest imported Revision>, |
+# 'revision_getter': lambda: ndb.Future with <latest imported Revision> |
# 'validator': lambda config: <raises ValueError on invalid format> |
# 'updater': lambda rev, config: True if applied, False if not. |
# 'use_authdb_transaction': True to call 'updater' in AuthDB transaction. |
@@ -479,26 +488,26 @@ def _update_oauth_config(rev, conf): |
_CONFIG_SCHEMAS = { |
'imports.cfg': { |
'proto_class': None, # importer configs are stored as text |
- 'revision_getter': _get_imports_config_revision, |
+ 'revision_getter': _get_imports_config_revision_async, |
'updater': _update_imports_config, |
'use_authdb_transaction': False, |
}, |
'ip_whitelist.cfg': { |
'proto_class': config_pb2.IPWhitelistConfig, |
- 'revision_getter': lambda: _get_authdb_config_rev('ip_whitelist.cfg'), |
+ 'revision_getter': lambda: _get_authdb_config_rev_async('ip_whitelist.cfg'), |
'updater': _update_ip_whitelist_config, |
'use_authdb_transaction': True, |
}, |
'oauth.cfg': { |
'proto_class': config_pb2.OAuthConfig, |
- 'revision_getter': lambda: _get_authdb_config_rev('oauth.cfg'), |
+ 'revision_getter': lambda: _get_authdb_config_rev_async('oauth.cfg'), |
'updater': _update_oauth_config, |
'use_authdb_transaction': True, |
}, |
'settings.cfg': { |
'proto_class': None, # settings are stored as text in datastore |
'default': '', # it's fine if config file is not there |
- 'revision_getter': lambda: _get_service_config_rev('settings.cfg'), |
+ 'revision_getter': lambda: _get_service_config_rev_async('settings.cfg'), |
'updater': lambda rev, c: _update_service_config('settings.cfg', rev, c), |
'use_authdb_transaction': False, |
}, |