# HG changeset patch # User Ludovic Chabant # Date 1436421089 25200 # Node ID cb3446be44b7538d208a85227594df406e82fcf8 # Parent 96d363e2da4bc80bf5335669af03fda656d579ff bake: Abort "render first" jobs if we start using other pages. This prevents the baker from having one worker stuck on a very long job, like rendering the index page of a blog with lots and lots of posts. diff -r 96d363e2da4b -r cb3446be44b7 piecrust/baking/worker.py --- a/piecrust/baking/worker.py Mon Jul 06 21:32:40 2015 -0700 +++ b/piecrust/baking/worker.py Wed Jul 08 22:51:29 2015 -0700 @@ -3,6 +3,7 @@ from piecrust.app import PieCrust from piecrust.baking.records import BakeRecord, _get_transition_key from piecrust.baking.single import PageBaker, BakingError +from piecrust.environment import AbortedSourceUseError from piecrust.rendering import ( QualifiedPage, PageRenderingContext, render_page_segments) from piecrust.routing import create_route_metadata @@ -147,18 +148,25 @@ route_metadata = create_route_metadata(page) qp = QualifiedPage(page, route, route_metadata) ctx = PageRenderingContext(qp) + self.app.env.abort_source_use = True result = { 'path': fac.path, + 'aborted': False, 'errors': None} logger.debug("Preparing page: %s" % fac.ref_spec) try: render_page_segments(ctx) + except AbortedSourceUseError: + logger.debug("Page %s was aborted." % fac.ref_spec) + result['aborted'] = True except Exception as ex: logger.debug("Got rendering error. Sending it to master.") result['errors'] = _get_errors(ex) if self.ctx.debug: logger.exception(ex) + finally: + self.app.env.abort_source_use = False return result diff -r 96d363e2da4b -r cb3446be44b7 piecrust/data/iterators.py --- a/piecrust/data/iterators.py Mon Jul 06 21:32:40 2015 -0700 +++ b/piecrust/data/iterators.py Wed Jul 08 22:51:29 2015 -0700 @@ -1,6 +1,8 @@ import logging from piecrust.data.filters import PaginationFilter +from piecrust.environment import AbortedSourceUseError from piecrust.events import Event +from piecrust.sources.base import PageSource from piecrust.sources.interfaces import IPaginationSource @@ -289,6 +291,13 @@ if self._pagesData is not None: return + if (self._current_page is not None and + self._current_page.app.env.abort_source_use and + isinstance(self._source, PageSource)): + logger.debug("Aborting iteration from %s." % + self._current_page.ref_spec) + raise AbortedSourceUseError() + self._ensureSorter() it_chain = self._pages diff -r 96d363e2da4b -r cb3446be44b7 piecrust/environment.py --- a/piecrust/environment.py Mon Jul 06 21:32:40 2015 -0700 +++ b/piecrust/environment.py Wed Jul 08 22:51:29 2015 -0700 @@ -7,6 +7,10 @@ logger = logging.getLogger(__name__) +class AbortedSourceUseError(Exception): + pass + + class ExecutionInfo(object): def __init__(self, page, render_ctx): self.page = page @@ -60,6 +64,7 @@ self.fs_caches = { 'renders': self.rendered_segments_repository} self.fs_cache_only_for_main_page = False + self.abort_source_use = False self._default_layout_extensions = None self._timers = {}