comparison piecrust/baking/baker.py @ 1014:071f30aa04bb

bake: Do template caching in a background job if possible.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 28 Nov 2017 21:28:15 -0800
parents c4cf3cfe2726
children fa489c5e829e
comparison
equal deleted inserted replaced
1013:6370ab74b2d5 1014:071f30aa04bb
96 96
97 # Done with all the setup, let's start the actual work. 97 # Done with all the setup, let's start the actual work.
98 logger.info(format_timed(start_time, "setup baker")) 98 logger.info(format_timed(start_time, "setup baker"))
99 99
100 # Load all sources, pre-cache templates. 100 # Load all sources, pre-cache templates.
101 load_start_time = time.perf_counter()
102 self._startPopulateTemplateCaches(pool)
101 self._loadSources(ppmngr) 103 self._loadSources(ppmngr)
102 self._populateTemplateCaches() 104 self._endPopulateTemplateCache(pool)
105 logger.info(format_timed(load_start_time, "loaded site content"))
103 106
104 # Bake the realms. 107 # Bake the realms.
105 self._bakeRealms(pool, ppmngr, record_histories) 108 self._bakeRealms(pool, ppmngr, record_histories)
106 109
107 # Handle deletions, collapse records, etc. 110 # Handle deletions, collapse records, etc.
204 "command was invoked with all pipelines filtered " 207 "command was invoked with all pipelines filtered "
205 "out. There's nothing to do.") 208 "out. There's nothing to do.")
206 return ppmngr 209 return ppmngr
207 210
208 def _loadSources(self, ppmngr): 211 def _loadSources(self, ppmngr):
209 start_time = time.perf_counter()
210
211 for ppinfo in ppmngr.getPipelineInfos(): 212 for ppinfo in ppmngr.getPipelineInfos():
212 rec = ppinfo.record_history.current 213 rec = ppinfo.record_history.current
213 rec_entries = ppinfo.pipeline.loadAllContents() 214 rec_entries = ppinfo.pipeline.loadAllContents()
214 if rec_entries is not None: 215 if rec_entries is not None:
215 for e in rec_entries: 216 for e in rec_entries:
216 rec.addEntry(e) 217 rec.addEntry(e)
217 218
218 stats = self.app.env.stats 219 def _startPopulateTemplateCaches(self, pool):
219 stats.stepTimer('LoadSourceContents', time.perf_counter() - start_time) 220 # If we can, cache templates in a worker process, so we can load
220 logger.info(format_timed(start_time, "loaded site content")) 221 # the sources' pages in the main process in the meantime.
221 222 # But if we don't have any workers, well, we'll have to make do
222 def _populateTemplateCaches(self): 223 # in the `_endPopulateTemplateCache` method.
223 start_time = time.perf_counter() 224 if pool.pool_size == 0:
224 225 return
225 for eng in self.app.plugin_loader.getTemplateEngines(): 226
226 eng.populateCache() 227 pool._callback = None
227 228 pool._error_callback = None
228 stats = self.app.env.stats 229 job = {'job_spec': ('__special__', 'populate_template_cache')}
229 stats.stepTimer('CacheTemplates', time.perf_counter() - start_time) 230 pool.queueJobs([job])
230 logger.info(format_timed(start_time, "cache templates")) 231
232 def _endPopulateTemplateCache(self, pool):
233 if pool.pool_size == 0:
234 # No workers... load the templates synchronously.
235 for eng in self.app.plugin_loader.getTemplateEngines():
236 eng.populateCache()
237 else:
238 # Wait for the job to finish.
239 pool.wait()
240 pool._callback = self._handleWorkerResult
241 pool._error_callback = self._handleWorkerError
231 242
232 def _bakeRealms(self, pool, ppmngr, record_histories): 243 def _bakeRealms(self, pool, ppmngr, record_histories):
233 # Bake the realms -- user first, theme second, so that a user item 244 # Bake the realms -- user first, theme second, so that a user item
234 # can override a theme item. 245 # can override a theme item.
235 # Do this for as many times as we have pipeline passes left to do. 246 # Do this for as many times as we have pipeline passes left to do.