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

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

Issue 15009006: Docserver: refactor Servlet, ObjectStore, and ServerInstance architecture to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix example zipper Created 7 years, 7 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/cron_servlet.py
diff --git a/chrome/common/extensions/docs/server2/cron_servlet.py b/chrome/common/extensions/docs/server2/cron_servlet.py
index e768aa373132597a4186bd877003356d4260f064..f823988c995689aaf82c694f86607bbed66afc1a 100644
--- a/chrome/common/extensions/docs/server2/cron_servlet.py
+++ b/chrome/common/extensions/docs/server2/cron_servlet.py
@@ -6,16 +6,61 @@ import logging
import time
import traceback
-from appengine_wrappers import DeadlineExceededError, logservice
+from appengine_wrappers import DeadlineExceededError, IsDevServer, logservice
from branch_utility import BranchUtility
+from caching_file_system import CachingFileSystem
+from github_file_system import GithubFileSystem
+from object_store_creator import ObjectStoreCreator
from render_servlet import RenderServlet
from server_instance import ServerInstance
from servlet import Servlet, Request, Response
+from subversion_file_system import SubversionFileSystem
import svn_constants
+from third_party.json_schema_compiler.memoize import memoize
+
+def _CreateServerInstanceForChannel(channel, delegate):
+ object_store_creator = ObjectStoreCreator(channel, start_empty=True)
+ branch = (delegate.CreateBranchUtility(object_store_creator)
+ .GetBranchForChannel(channel))
+ host_file_system = CachingFileSystem(
+ delegate.CreateHostFileSystemForBranch(branch),
+ object_store_creator)
+ app_samples_file_system = delegate.CreateAppSamplesFileSystem(
+ object_store_creator)
+ return ServerInstance(channel,
+ object_store_creator,
+ host_file_system,
+ app_samples_file_system)
+
+class _SingletonRenderServletDelegate(RenderServlet.Delegate):
+ def __init__(self, server_instance):
+ self._server_instance = server_instance
+
+ def CreateServerInstanceForChannel(self, channel):
+ return self._server_instance
class CronServlet(Servlet):
'''Servlet which runs a cron job.
'''
+ def __init__(self, request, delegate_for_test=None):
+ Servlet.__init__(self, request)
+ self._delegate = delegate_for_test or CronServlet.Delegate()
+
+ class Delegate(object):
+ '''Allow runtime dependencies to be overridden for testing.
+ '''
+ def CreateBranchUtility(self, object_store_creator):
+ return BranchUtility.Create(object_store_creator)
+
+ def CreateHostFileSystemForBranch(self, branch):
+ return SubversionFileSystem.Create(branch)
+
+ def CreateAppSamplesFileSystem(self, object_store_creator):
+ # TODO(kalman): CachingFileSystem wrapper for GithubFileSystem, but it's
+ # not supported yet (see comment there).
+ return (EmptyDirFileSystem() if IsDevServer() else
+ GithubFileSystem.Create(object_store_creator))
+
def Get(self):
# Crons often time out, and when they do *and* then eventually try to
# flush logs they die. Turn off autoflush and manually do so at the end.
@@ -35,7 +80,14 @@ class CronServlet(Servlet):
channel = self._request.path.strip('/')
logging.info('cron/%s: starting' % channel)
- server_instance = ServerInstance.CreateOnline(channel)
+ # This is returned every time RenderServlet wants to create a new
+ # ServerInstance.
+ server_instance = _CreateServerInstanceForChannel(channel, self._delegate)
+
+ def get_via_render_servlet(path):
+ return RenderServlet(
+ Request(path, self._request.headers),
+ _SingletonRenderServletDelegate(server_instance)).Get()
def run_cron_for_dir(d, path_prefix=''):
success = True
@@ -49,8 +101,7 @@ class CronServlet(Servlet):
error = None
path = '%s%s' % (path_prefix, f)
try:
- response = RenderServlet(Request(path, self._request.headers)).Get(
- server_instance=server_instance)
+ response = get_via_render_servlet(path)
if response.status != 200:
error = 'Got %s response' % response.status
except DeadlineExceededError:
@@ -70,22 +121,52 @@ class CronServlet(Servlet):
return success
success = True
- for path, path_prefix in (
- # Note: rendering the public templates will pull in all of the private
- # templates.
- (svn_constants.PUBLIC_TEMPLATE_PATH, ''),
- # Note: rendering the public templates will have pulled in the .js and
- # manifest.json files (for listing examples on the API reference pages),
- # but there are still images, CSS, etc.
- (svn_constants.STATIC_PATH, 'static/'),
- (svn_constants.EXAMPLES_PATH, 'extensions/examples/')):
- try:
- # Note: don't try to short circuit any of this stuff. We want to run
- # the cron for all the directories regardless of intermediate failures.
+ try:
+ # Render all of the publically accessible files.
cduvall 2013/05/08 03:09:14 publically -> publicly
not at google - send to devlin 2013/05/08 18:26:19 Done.
+ for path, path_prefix in (
+ # Note: rendering the public templates will pull in all of the private
+ # templates.
+ (svn_constants.PUBLIC_TEMPLATE_PATH, ''),
+ # Note: rendering the public templates will have pulled in the .js
+ # and manifest.json files (for listing examples on the API reference
+ # pages), but there are still images, CSS, etc.
+ (svn_constants.STATIC_PATH, 'static/'),
+ (svn_constants.EXAMPLES_PATH, 'extensions/examples/')):
+ # Note: don't try to short circuit any of this stuff. We want to run
+ # the cron for all the directories regardless of intermediate
+ # failures.
success = run_cron_for_dir(path, path_prefix=path_prefix) and success
- except DeadlineExceededError:
- success = False
- break
+
+ # TODO(kalman): Generic way for classes to request cron access. The next
+ # two special cases are ugly. It would potentially greatly speed up cron
+ # runs, too.
+
+ # Extension examples have zip files too. Well, so do apps, but the app
+ # file system doesn't get the Offline treatment so they don't need cron.
+ manifest_json = '/manifest.json'
+ example_zips = [
+ '%s.zip' % filename[:-len(manifest_json)]
+ for filename in server_instance.content_cache.GetFromFileListing(
+ svn_constants.EXAMPLES_PATH)
+ if filename.endswith(manifest_json)]
+ logging.info('cron/%s: rendering %s example zips...' % (
+ channel, len(example_zips)))
+ start_time = time.time()
+ try:
+ success = success and all(
+ get_via_render_servlet('extensions/examples/%s' % z).status == 200
+ for z in example_zips)
+ finally:
+ logging.info('cron/%s: rendering %s example zips took %s seconds' % (
+ channel, len(example_zips), time.time() - start_time))
+
+ # Also trigger a redirect so that PathCanonicalizer has an opportunity to
+ # cache file listings.
+ logging.info('cron/%s: triggering a redirect...' % channel)
+ redirect_response = get_via_render_servlet('storage.html')
+ success = success and redirect_response.status == 302
+ except DeadlineExceededError:
+ success = False
logging.info('cron/%s: finished' % channel)

Powered by Google App Engine
This is Rietveld 408576698