| Index: chrome/common/extensions/docs/server2/api_models.py
|
| diff --git a/chrome/common/extensions/docs/server2/api_models.py b/chrome/common/extensions/docs/server2/api_models.py
|
| index ac164fb4e6d331288c797e0449ee424df649d9b3..ab6e0bd5db343204f6f3c1dad4f0ce5a92c7e64f 100644
|
| --- a/chrome/common/extensions/docs/server2/api_models.py
|
| +++ b/chrome/common/extensions/docs/server2/api_models.py
|
| @@ -8,8 +8,9 @@ from compiled_file_system import SingleFile, Unicode
|
| from extensions_paths import API_PATHS
|
| from features_bundle import HasParent, GetParentName
|
| from file_system import FileNotFoundError
|
| -from future import All, Future
|
| +from future import All, Future, Race
|
| from operator import itemgetter
|
| +from path_util import Join
|
| from platform_util import PlatformToExtensionType
|
| from schema_util import ProcessSchema
|
| from third_party.json_schema_compiler.json_schema import DeleteNodes
|
| @@ -58,6 +59,7 @@ class APIModels(object):
|
| object_store_creator,
|
| platform):
|
| self._features_bundle = features_bundle
|
| + self._file_system = file_system
|
| self._platform = PlatformToExtensionType(platform)
|
| self._model_cache = compiled_fs_factory.Create(
|
| file_system, self._CreateAPIModel, APIModels, category=self._platform)
|
| @@ -86,7 +88,10 @@ class APIModels(object):
|
| return [name for name, feature in api_features.iteritems()
|
| if not HasParent(name, feature, api_features)]
|
|
|
| - def GetModel(self, api_name):
|
| + def _GetPotentialPathsForModel(self, api_name):
|
| + '''Returns the list of file system paths that the model for |api_name|
|
| + might be located at.
|
| + '''
|
| # By default |api_name| is assumed to be given without a path or extension,
|
| # so combinations of known paths and extension types will be searched.
|
| api_extensions = ('.json', '.idl')
|
| @@ -116,19 +121,13 @@ class APIModels(object):
|
| 'devtools', file_name.replace(basename,
|
| basename.replace('devtools_' , '')))
|
|
|
| - futures = [self._model_cache.GetFromFile(
|
| - posixpath.join(path, '%s%s' % (file_name, ext)))
|
| - for ext in api_extensions
|
| - for path in api_paths]
|
| - def resolve():
|
| - for future in futures:
|
| - try:
|
| - return future.Get()
|
| - # Either the file wasn't found or there was no schema for the file
|
| - except (FileNotFoundError, ValueError): pass
|
| - # Propagate the first error if neither were found.
|
| - futures[0].Get()
|
| - return Future(callback=resolve)
|
| + return [Join(path, file_name + ext) for ext in api_extensions
|
| + for path in api_paths]
|
| +
|
| + def GetModel(self, api_name):
|
| + futures = [self._model_cache.GetFromFile(path)
|
| + for path in self._GetPotentialPathsForModel(api_name)]
|
| + return Race(futures, except_pass=(FileNotFoundError, ValueError))
|
|
|
| def GetContentScriptAPIs(self):
|
| '''Creates a dict of APIs and nodes supported by content scripts in
|
| @@ -169,10 +168,6 @@ class APIModels(object):
|
| return content_script_apis
|
| return Future(callback=resolve)
|
|
|
| - def Cron(self):
|
| - futures = [self.GetModel(name) for name in self.GetNames()]
|
| - return All(futures, except_pass=(FileNotFoundError, ValueError))
|
| -
|
| def IterModels(self):
|
| future_models = [(name, self.GetModel(name)) for name in self.GetNames()]
|
| for name, future_model in future_models:
|
| @@ -182,3 +177,23 @@ class APIModels(object):
|
| continue
|
| if model:
|
| yield name, model
|
| +
|
| + def Cron(self):
|
| + def map_cron_paths(op):
|
| + results = []
|
| + for name in self.GetNames():
|
| + results += [op(path) for path in self._GetPotentialPathsForModel(name)]
|
| + return results
|
| +
|
| + # Immediately stat everything so that files are guaranteed to be eventually
|
| + # up to date. See http://crbug.com/398042 for background.
|
| + # XXX see comment below, return a future for this, hopefully crons will
|
| + # complete and we don't need to immediately resolve?
|
| + All(map_cron_paths(self._file_system.StatAsync),
|
| + except_pass=(FileNotFoundError, ValueError)).Get()
|
| +
|
| + # Update content in the future.
|
| + # XXX don't do this for now, see how the crons and instances behave with
|
| + # just getting the versions.
|
| + return All(map_cron_paths(self.GetModel),
|
| + except_pass=(FileNotFoundError, ValueError))
|
|
|