blob: 47a9be4b5eb148ad419fd8fc5e1ca3d076dca030 [file] [log] [blame]
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01001# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5from appengine_wrappers import IsDevServer
6from branch_utility import BranchUtility
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +01007from compiled_file_system import CompiledFileSystem
8from empty_dir_file_system import EmptyDirFileSystem
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +01009from github_file_system import GithubFileSystem
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010010from host_file_system_creator import HostFileSystemCreator
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010011from third_party.json_schema_compiler.memoize import memoize
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010012from render_servlet import RenderServlet
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010013from object_store_creator import ObjectStoreCreator
14from server_instance import ServerInstance
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010015
Ben Murdochbb1529c2013-08-08 10:24:53 +010016class OfflineRenderServletDelegate(RenderServlet.Delegate):
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010017 '''AppEngine instances should never need to call out to SVN. That should only
18 ever be done by the cronjobs, which then write the result into DataStore,
19 which is as far as instances look. To enable this, crons can pass a custom
20 (presumably online) ServerInstance into Get().
21
22 Why? SVN is slow and a bit flaky. Cronjobs failing is annoying but temporary.
23 Instances failing affects users, and is really bad.
24
25 Anyway - to enforce this, we actually don't give instances access to SVN. If
26 anything is missing from datastore, it'll be a 404. If the cronjobs don't
27 manage to catch everything - uhoh. On the other hand, we'll figure it out
28 pretty soon, and it also means that legitimate 404s are caught before a round
29 trip to SVN.
30 '''
31 def __init__(self, delegate):
32 self._delegate = delegate
33
34 @memoize
Ben Murdochca12bfa2013-07-23 11:17:05 +010035 def CreateServerInstance(self):
36 object_store_creator = ObjectStoreCreator(start_empty=False)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010037 branch_utility = self._delegate.CreateBranchUtility(object_store_creator)
38 host_file_system_creator = self._delegate.CreateHostFileSystemCreator(
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010039 object_store_creator)
Ben Murdochca12bfa2013-07-23 11:17:05 +010040 host_file_system = host_file_system_creator.Create()
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010041 app_samples_file_system = self._delegate.CreateAppSamplesFileSystem(
42 object_store_creator)
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +010043 compiled_host_fs_factory = CompiledFileSystem.Factory(
44 host_file_system,
45 object_store_creator)
Ben Murdochca12bfa2013-07-23 11:17:05 +010046 return ServerInstance(object_store_creator,
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010047 host_file_system,
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +010048 app_samples_file_system,
Ben Murdochca12bfa2013-07-23 11:17:05 +010049 '',
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010050 compiled_host_fs_factory,
51 branch_utility,
52 host_file_system_creator)
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010053
54class InstanceServlet(object):
55 '''Servlet for running on normal AppEngine instances.
56 Create this via GetConstructor() so that cache state can be shared amongst
57 them via the memoizing Delegate.
58 '''
59 class Delegate(object):
60 '''Allow runtime dependencies to be overriden for testing.
61 '''
62 def CreateBranchUtility(self, object_store_creator):
63 return BranchUtility.Create(object_store_creator)
64
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010065 def CreateHostFileSystemCreator(self, object_store_creator):
66 return HostFileSystemCreator(object_store_creator, offline=True)
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010067
68 def CreateAppSamplesFileSystem(self, object_store_creator):
69 # TODO(kalman): OfflineServerInstance wrapper for GithubFileSystem, but
70 # the cron job doesn't crawl the samples yet.
71 return (EmptyDirFileSystem() if IsDevServer() else
72 GithubFileSystem.Create(object_store_creator))
73
74 @staticmethod
75 def GetConstructor(delegate_for_test=None):
Ben Murdochbb1529c2013-08-08 10:24:53 +010076 render_servlet_delegate = OfflineRenderServletDelegate(
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +010077 delegate_for_test or InstanceServlet.Delegate())
78 return lambda request: RenderServlet(request, render_servlet_delegate)
79
80 # NOTE: if this were a real Servlet it would implement a Get() method, but
81 # GetConstructor returns an appropriate lambda function (Request -> Servlet).