Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 1 | # 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 | |
| 5 | from appengine_wrappers import IsDevServer |
| 6 | from branch_utility import BranchUtility |
Torne (Richard Coles) | a93a17c | 2013-05-15 11:34:50 +0100 | [diff] [blame] | 7 | from compiled_file_system import CompiledFileSystem |
| 8 | from empty_dir_file_system import EmptyDirFileSystem |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 9 | from github_file_system import GithubFileSystem |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 10 | from host_file_system_creator import HostFileSystemCreator |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 11 | from third_party.json_schema_compiler.memoize import memoize |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 12 | from render_servlet import RenderServlet |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 13 | from object_store_creator import ObjectStoreCreator |
| 14 | from server_instance import ServerInstance |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 15 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 16 | class OfflineRenderServletDelegate(RenderServlet.Delegate): |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 17 | '''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 Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 35 | def CreateServerInstance(self): |
| 36 | object_store_creator = ObjectStoreCreator(start_empty=False) |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 37 | branch_utility = self._delegate.CreateBranchUtility(object_store_creator) |
| 38 | host_file_system_creator = self._delegate.CreateHostFileSystemCreator( |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 39 | object_store_creator) |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 40 | host_file_system = host_file_system_creator.Create() |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 41 | app_samples_file_system = self._delegate.CreateAppSamplesFileSystem( |
| 42 | object_store_creator) |
Torne (Richard Coles) | a93a17c | 2013-05-15 11:34:50 +0100 | [diff] [blame] | 43 | compiled_host_fs_factory = CompiledFileSystem.Factory( |
| 44 | host_file_system, |
| 45 | object_store_creator) |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 46 | return ServerInstance(object_store_creator, |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 47 | host_file_system, |
Torne (Richard Coles) | a93a17c | 2013-05-15 11:34:50 +0100 | [diff] [blame] | 48 | app_samples_file_system, |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 49 | '', |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 50 | compiled_host_fs_factory, |
| 51 | branch_utility, |
| 52 | host_file_system_creator) |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 53 | |
| 54 | class 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 Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 65 | def CreateHostFileSystemCreator(self, object_store_creator): |
| 66 | return HostFileSystemCreator(object_store_creator, offline=True) |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 67 | |
| 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 Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 76 | render_servlet_delegate = OfflineRenderServletDelegate( |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 77 | 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). |