Mercurial > p > roundup > code
comparison roundup/cgi/wsgi_handler.py @ 6747:d32d43e4a5ba
wsgi can cache tracker instance enabled by feature flag.
Patch by Marcus Priesch caches a loaded tracker instance and reuse it
for future client sessions.
It is enabled by a feature flag in wsgi.py since it arrived during the
2.2.0 beta period.
The provided wsgi.py is modified to enable it. Testing is run with
flag enabled and disabled.
Ralf Schlatterbeck and Marcus tested it on one of their larger more
complex trackers and it sped up the response time to a client request
by a factor of 3 (270ms down to about 80-85ms).
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sat, 02 Jul 2022 14:04:00 -0400 |
| parents | 0da655d1498d |
| children | 07ce4e4110f5 |
comparison
equal
deleted
inserted
replaced
| 6746:efa203f3c696 | 6747:d32d43e4a5ba |
|---|---|
| 72 raise ValueError('start_response() not called') | 72 raise ValueError('start_response() not called') |
| 73 return self.__wfile | 73 return self.__wfile |
| 74 | 74 |
| 75 | 75 |
| 76 class RequestDispatcher(object): | 76 class RequestDispatcher(object): |
| 77 def __init__(self, home, debug=False, timing=False, lang=None): | 77 def __init__(self, home, debug=False, timing=False, lang=None, |
| 78 feature_flags=None): | |
| 78 assert os.path.isdir(home), '%r is not a directory' % (home,) | 79 assert os.path.isdir(home), '%r is not a directory' % (home,) |
| 79 self.home = home | 80 self.home = home |
| 80 self.debug = debug | 81 self.debug = debug |
| 81 self.timing = timing | 82 self.timing = timing |
| 83 self.feature_flags= feature_flags or {} | |
| 84 self.tracker = None | |
| 82 if lang: | 85 if lang: |
| 83 self.translator = TranslationService.get_translation(lang, | 86 self.translator = TranslationService.get_translation(lang, |
| 84 tracker_home=home) | 87 tracker_home=home) |
| 85 else: | 88 else: |
| 86 self.translator = None | 89 self.translator = None |
| 87 self.preload() | 90 |
| 91 if "cache_tracker" in self.feature_flags: | |
| 92 self.tracker = roundup.instance.open(self.home, not self.debug) | |
| 93 else: | |
| 94 self.preload() | |
| 88 | 95 |
| 89 def __call__(self, environ, start_response): | 96 def __call__(self, environ, start_response): |
| 90 """Initialize with `apache.Request` object""" | 97 """Initialize with `apache.Request` object""" |
| 91 request = RequestHandler(environ, start_response) | 98 request = RequestHandler(environ, start_response) |
| 92 | 99 |
| 114 # form. | 121 # form. |
| 115 form = None | 122 form = None |
| 116 else: | 123 else: |
| 117 form = BinaryFieldStorage(fp=environ['wsgi.input'], environ=environ) | 124 form = BinaryFieldStorage(fp=environ['wsgi.input'], environ=environ) |
| 118 | 125 |
| 119 with self.get_tracker() as tracker: | 126 if "cache_tracker" in self.feature_flags: |
| 120 client = tracker.Client(tracker, request, environ, form, | 127 client = self.tracker.Client(self.tracker, request, environ, form, |
| 121 self.translator) | 128 self.translator) |
| 122 try: | 129 try: |
| 123 client.main() | 130 client.main() |
| 124 except roundup.cgi.client.NotFound: | 131 except roundup.cgi.client.NotFound: |
| 125 request.start_response([('Content-Type', 'text/html')], 404) | 132 request.start_response([('Content-Type', 'text/html')], 404) |
| 126 request.wfile.write(s2b('Not found: %s' % | 133 request.wfile.write(s2b('Not found: %s' % |
| 127 html_escape(client.path))) | 134 html_escape(client.path))) |
| 135 else: | |
| 136 with self.get_tracker() as tracker: | |
| 137 client = tracker.Client(tracker, request, environ, form, | |
| 138 self.translator) | |
| 139 try: | |
| 140 client.main() | |
| 141 except roundup.cgi.client.NotFound: | |
| 142 request.start_response([('Content-Type', 'text/html')], 404) | |
| 143 request.wfile.write(s2b('Not found: %s' % | |
| 144 html_escape(client.path))) | |
| 128 | 145 |
| 129 # all body data has been written using wfile | 146 # all body data has been written using wfile |
| 130 return [] | 147 return [] |
| 131 | 148 |
| 132 def preload(self): | 149 def preload(self): |
