Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Unified Diff: chrome/common/extensions/docs/server2/server_instance.py

Issue 13470005: Refactor the devserver to make it easier to control caching (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cache static files in cron, fix path canonicalizer bug Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/server2/server_instance.py
diff --git a/chrome/common/extensions/docs/server2/server_instance.py b/chrome/common/extensions/docs/server2/server_instance.py
index c3ecabc664f5f91dd611c664044a52076a85fb32..81d1f68ec29a3c2a54366028560c2207ead61ea3 100644
--- a/chrome/common/extensions/docs/server2/server_instance.py
+++ b/chrome/common/extensions/docs/server2/server_instance.py
@@ -6,48 +6,182 @@ from fnmatch import fnmatch
import mimetypes
import os
+from api_data_source import APIDataSource
+from api_list_data_source import APIListDataSource
+from appengine_blobstore import AppEngineBlobstore
+from appengine_url_fetcher import AppEngineUrlFetcher
+from branch_utility import BranchUtility
+from compiled_file_system import CompiledFileSystem
+from example_zipper import ExampleZipper
from file_system import FileNotFoundError
-import compiled_file_system as compiled_fs
-
-STATIC_DIR_PREFIX = 'docs'
-DOCS_PATH = 'docs'
+from github_file_system import GithubFileSystem
+from in_memory_object_store import InMemoryObjectStore
+from intro_data_source import IntroDataSource
+from local_file_system import LocalFileSystem
+from caching_file_system import CachingFileSystem
+from object_store_creator import ObjectStoreCreator
+from path_canonicalizer import PathCanonicalizer
+from reference_resolver import ReferenceResolver
+from samples_data_source import SamplesDataSource
+from sidenav_data_source import SidenavDataSource
+from subversion_file_system import SubversionFileSystem
+import svn_constants
+from template_data_source import TemplateDataSource
+from third_party.json_schema_compiler.model import UnixName
+import url_constants
def _IsBinaryMimetype(mimetype):
return any(mimetype.startswith(prefix)
for prefix in ['audio', 'image', 'video'])
class ServerInstance(object):
- """This class is used to hold a data source and fetcher for an instance of a
- server. Each new branch will get its own ServerInstance.
- """
- def __init__(self,
- template_data_source_factory,
- example_zipper,
- cache_factory):
- self._template_data_source_factory = template_data_source_factory
- self._example_zipper = example_zipper
- self._cache = cache_factory.Create(lambda _, x: x, compiled_fs.STATIC)
+ '''Per-instance per-branch state.
+ '''
+ _instances = {}
+
+ branch_utility = None
+ github_file_system = None
+
+ @staticmethod
+ def GetOrCreate(channel):
+ branch_utility = ServerInstance.branch_utility
cduvall 2013/04/08 07:09:24 is it necessary to assign ServerInstance.branch_ut
not at google - send to devlin 2013/04/08 12:21:21 Done. For GithubFileSystem too.
+ if branch_utility is None:
+ branch_utility = BranchUtility(url_constants.OMAHA_PROXY_URL,
+ AppEngineUrlFetcher())
+ ServerInstance.branch_utility = branch_utility
+
+ branch = branch_utility.GetBranchNumberForChannelName(channel)
+
+ # Use the branch as the key to |_instances| since the branch data is
+ # predictable while the channel data (channels can swich branches) isn't.
+ instance = ServerInstance._instances.get(branch)
+ if instance is None:
+ instance = ServerInstance._CreateForProduction(channel, branch)
+ ServerInstance._instances[branch] = instance
+ return instance
+
+ @staticmethod
+ def _CreateForProduction(channel, branch):
+ if branch == 'trunk':
+ svn_url = '/'.join((url_constants.SVN_TRUNK_URL,
+ 'src',
+ svn_constants.EXTENSIONS_PATH))
+ else:
+ svn_url = '/'.join((url_constants.SVN_BRANCH_URL,
+ branch,
+ 'src',
+ svn_constants.EXTENSIONS_PATH))
+
+ viewvc_url = svn_url.replace(url_constants.SVN_URL,
+ url_constants.VIEWVC_URL)
+
+ svn_file_system = CachingFileSystem(
+ SubversionFileSystem(AppEngineUrlFetcher(svn_url),
+ AppEngineUrlFetcher(viewvc_url)))
+
+ github_file_system = ServerInstance.github_file_system
+ if github_file_system is None:
+ github_file_system = GithubFileSystem(
+ AppEngineUrlFetcher(url_constants.GITHUB_URL),
+ AppEngineBlobstore())
+ ServerInstance.github_file_system = github_file_system
+
+ return ServerInstance(channel, svn_file_system, github_file_system)
+
+ @staticmethod
+ def CreateForTest(file_system):
+ return ServerInstance('test', file_system, None)
+
+ def __init__(self, channel, svn_file_system, github_file_system):
+ self.svn_file_system = svn_file_system
+
+ self.github_file_system = github_file_system
+
+ self.compiled_fs_factory = CompiledFileSystem.Factory(svn_file_system)
+
+ self.api_list_data_source_factory = APIListDataSource.Factory(
+ self.compiled_fs_factory,
+ svn_constants.API_PATH,
+ svn_constants.PUBLIC_TEMPLATE_PATH)
+
+ self.api_data_source_factory = APIDataSource.Factory(
+ self.compiled_fs_factory,
+ svn_constants.API_PATH)
+
+ self.ref_resolver_factory = ReferenceResolver.Factory(
+ self.api_data_source_factory,
+ self.api_list_data_source_factory)
+
+ self.api_data_source_factory.SetReferenceResolverFactory(
+ self.ref_resolver_factory)
+
+ self.samples_data_source_factory = SamplesDataSource.Factory(
+ channel,
+ self.svn_file_system,
+ ServerInstance.github_file_system,
+ self.ref_resolver_factory,
+ svn_constants.EXAMPLES_PATH)
+
+ self.api_data_source_factory.SetSamplesDataSourceFactory(
+ self.samples_data_source_factory)
+
+ self.intro_data_source_factory = IntroDataSource.Factory(
+ self.compiled_fs_factory,
+ self.ref_resolver_factory,
+ [svn_constants.INTRO_PATH, svn_constants.ARTICLE_PATH])
+
+ self.sidenav_data_source_factory = SidenavDataSource.Factory(
+ self.compiled_fs_factory,
+ svn_constants.JSON_PATH)
+
+ self.template_data_source_factory = TemplateDataSource.Factory(
+ channel,
+ self.api_data_source_factory,
+ self.api_list_data_source_factory,
+ self.intro_data_source_factory,
+ self.samples_data_source_factory,
+ self.sidenav_data_source_factory,
+ self.compiled_fs_factory,
+ self.ref_resolver_factory,
+ svn_constants.PUBLIC_TEMPLATE_PATH,
+ svn_constants.PRIVATE_TEMPLATE_PATH)
+
+ self.example_zipper = ExampleZipper(
+ self.svn_file_system,
+ self.compiled_fs_factory,
+ svn_constants.DOCS_PATH)
+
+ self.path_canonicalizer = PathCanonicalizer(
+ channel,
+ self.compiled_fs_factory)
+
+ self.content_cache = self.compiled_fs_factory.GetOrCreateIdentity()
def _FetchStaticResource(self, path, response):
"""Fetch a resource in the 'static' directory.
"""
mimetype = mimetypes.guess_type(path)[0] or 'text/plain'
try:
- result = self._cache.GetFromFile(STATIC_DIR_PREFIX + '/' + path,
- binary=_IsBinaryMimetype(mimetype))
+ result = self.content_cache.GetFromFile(
+ svn_constants.DOCS_PATH + '/' + path,
+ binary=_IsBinaryMimetype(mimetype))
except FileNotFoundError:
return None
response.headers['content-type'] = mimetype
return result
def Get(self, path, request, response):
- # TODO(cduvall): bundle up all the request-scoped data into a single object.
- templates = self._template_data_source_factory.Create(request, path)
+ templates = self.template_data_source_factory.Create(request, path)
+
+ if path.rsplit('/', 1)[-1] in ('favicon.ico', 'robots.txt'):
+ response.set_status(404)
+ response.out.write(templates.Render('404'))
+ return
content = None
if fnmatch(path, 'extensions/examples/*.zip'):
try:
- content = self._example_zipper.Create(
+ content = self.example_zipper.Create(
path[len('extensions/'):-len('.zip')])
response.headers['content-type'] = 'application/zip'
except FileNotFoundError:
@@ -55,8 +189,8 @@ class ServerInstance(object):
elif path.startswith('extensions/examples/'):
mimetype = mimetypes.guess_type(path)[0] or 'text/plain'
try:
- content = self._cache.GetFromFile(
- '%s/%s' % (DOCS_PATH, path[len('extensions/'):]),
+ content = self.content_cache.GetFromFile(
+ '%s/%s' % (svn_constants.DOCS_PATH, path[len('extensions/'):]),
binary=_IsBinaryMimetype(mimetype))
response.headers['content-type'] = 'text/plain'
except FileNotFoundError:

Powered by Google App Engine
This is Rietveld 408576698