Skip to content

Commit

Permalink
Try and make Jinja2 rendering sync to see if that reduces overhead. M…
Browse files Browse the repository at this point in the history
…ASSIVE STASH DOES NOT WORK.
  • Loading branch information
bartfeenstra committed Nov 11, 2020
1 parent 2004843 commit 1866bfe
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 37 deletions.
8 changes: 6 additions & 2 deletions betty/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import cProfile
import logging
import pstats
import shutil
import sys
from contextlib import suppress, contextmanager
Expand Down Expand Up @@ -132,5 +134,7 @@ async def _clear_caches():
@click.command(help='Generate a static site.')
@site_command
async def _generate(site: Site):
await parse.parse(site)
await generate.generate(site)
with cProfile.Profile() as pr:
await parse.parse(site)
await generate.generate(site)
pstats.Stats(pr).strip_dirs().sort_stats(pstats.SortKey.CUMULATIVE).print_stats()
15 changes: 5 additions & 10 deletions betty/functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,13 @@ def walk(item, attribute_name):
yield from walk(child, attribute_name)


async def asynciter(items: Union[Iterable, AsyncIterable]) -> AsyncIterable:
if hasattr(items, '__aiter__'):
async for item in items:
yield item
return
for item in items:
yield item


def sync(f):
if iscoroutine(f):
return asyncio.get_event_loop().run_until_complete(f)
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.get_event_loop()
return loop.run_until_complete(f)
elif iscoroutinefunction(f):
@wraps(f)
def _synced(*args, **kwargs):
Expand Down
33 changes: 17 additions & 16 deletions betty/jinja2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from geopy import units
from geopy.format import DEGREES_FORMAT
from jinja2 import Environment, select_autoescape, evalcontextfilter, escape, FileSystemLoader, contextfilter, Template
from jinja2.asyncsupport import auto_await
from jinja2.filters import prepare_map, make_attrgetter
from jinja2.runtime import Macro, resolve_or_missing, StrictUndefined
from jinja2.utils import htmlsafe_json_dumps
Expand All @@ -27,7 +26,6 @@
RESOURCE_TYPES
from betty.config import Configuration
from betty.fs import makedirs, hashfile, iterfiles
from betty.functools import walk, asynciter
from betty.html import HtmlProvider
from betty.importlib import import_any
from betty.json import JSONEncoder
Expand Down Expand Up @@ -96,7 +94,7 @@ def __init__(self, site: Site):
template_directory_paths = [join(path, 'templates') for path in site.assets.paths]

Environment.__init__(self,
enable_async=True,
# enable_async=True,
loader=FileSystemLoader(template_directory_paths),
undefined=StrictUndefined,
autoescape=select_autoescape(['html']),
Expand Down Expand Up @@ -219,7 +217,7 @@ def update_file_path(self, file_path: str) -> str:
return file_path[:-3]

async def render_string(self, template: str, template_arguments: TemplateArguments = None) -> str:
return await self._environment.from_string(template).render_async(**template_arguments)
return self._environment.from_string(template).render(**template_arguments)

async def render_file(self, file_path: str, template_arguments: TemplateArguments = None) -> None:
self._assert_file_path(file_path)
Expand All @@ -237,18 +235,21 @@ async def render_file(self, file_path: str, template_arguments: TemplateArgument
resource = '/'.join(resource_parts[1:])
template_arguments['file_resource'] = resource
with open(file_destination_path, 'w') as f:
f.write(await template.render_async(**template_arguments))
f.write(template.render(**template_arguments))
os.remove(file_path)

async def render_directory(self, directory_path: str, template_arguments: TemplateArguments = None) -> None:
await asyncio.gather(
*[self.render_file(file_path, template_arguments) for file_path in iterfiles(directory_path) if self.consumes_file_path(file_path)],
)
# await asyncio.gather(
# *[self.render_file(file_path, template_arguments) for file_path in iterfiles(directory_path) if self.consumes_file_path(file_path)],
# )
for file_path in iterfiles(directory_path):
if self.consumes_file_path(file_path):
await self.render_file(file_path, template_arguments)


async def _filter_flatten(items):
async for item in asynciter(items):
async for child in asynciter(item):
def _filter_flatten(items):
for item in items:
for child in item:
yield child


Expand Down Expand Up @@ -286,18 +287,18 @@ def _filter_format_degrees(degrees):


@contextfilter
async def _filter_map(*args, **kwargs):
def _filter_map(*args, **kwargs):
if len(args) == 3 and isinstance(args[2], Macro):
seq = args[1]
func = args[2]
else:
seq, func = prepare_map(args, kwargs)
if seq:
async for item in asynciter(seq):
yield await auto_await(func(item))
for item in seq:
yield func(item)


async def _filter_file(site: Site, file: File) -> str:
def _filter_file(site: Site, file: File) -> str:
file_directory_path = os.path.join(site.configuration.www_directory_path, 'file')

destination_name = '%s.%s' % (file.id, file.extension)
Expand All @@ -316,7 +317,7 @@ def _do_filter_file(file_path: str, destination_directory_path: str, destination
os.link(file_path, destination_file_path)


async def _filter_image(site: Site, file: File, width: Optional[int] = None, height: Optional[int] = None) -> str:
def _filter_image(site: Site, file: File, width: Optional[int] = None, height: Optional[int] = None) -> str:
if width is None and height is None:
raise ValueError('At least the width or height must be given.')

Expand Down
4 changes: 2 additions & 2 deletions betty/plugin/trees/assets/public/localized/people.json.j2
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
'id': person.id,
'label': person_label | striptags,
'url': person | url,
'parentIds': person.parents | map(attribute='id') | list,
'childIds': person.children | map(attribute='id') | list,
'parentIds': person.parents | list,
'childIds': person.children | list,
}
}) %}
{% endfor %}
Expand Down
2 changes: 2 additions & 0 deletions betty/plugin/wikipedia/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from betty.ancestry import Link, HasLinks, Resource
from betty.fs import makedirs
from betty.functools import sync
from betty.jinja2 import Jinja2Provider
from betty.locale import Localized, negotiate_locale
from betty.parse import PostParser
Expand Down Expand Up @@ -227,6 +228,7 @@ def filters(self) -> Dict[str, Callable]:
}

@contextfilter
@sync
async def _filter_wikipedia_links(self, context, links: Iterable[Link]) -> Iterable[Entry]:
locale = parse_locale(resolve_or_missing(context, 'locale'), '-')[0]
return filter(None, await asyncio.gather(*[self._filter_wikipedia_link(locale, link) for link in links]))
Expand Down
15 changes: 8 additions & 7 deletions betty/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ class Index:
def __init__(self, site: Site):
self._site = site

async def build(self) -> Iterable[Dict]:
return filter(None, await asyncio.gather(*[
*[self._build_person(person) for person in self._site.ancestry.people.values()],
*[self._build_place(place) for place in self._site.ancestry.places.values()],
*[self._build_file(file) for file in self._site.ancestry.files.values()],
]))
def build(self) -> Iterable[Dict]:
return [{}]
# return filter(None, await asyncio.gather(*[
# *[self._build_person(person) for person in self._site.ancestry.people.values()],
# *[self._build_place(place) for place in self._site.ancestry.places.values()],
# *[self._build_file(file) for file in self._site.ancestry.files.values()],
# ]))

async def _render_resource(self, resource: Resource):
return await self._site.jinja2_environment.get_template('search/result-%s.html.j2' % resource.resource_type_name).render_async({
return self._site.jinja2_environment.get_template('search/result-%s.html.j2' % resource.resource_type_name).render({
resource.resource_type_name: resource,
})

Expand Down

0 comments on commit 1866bfe

Please sign in to comment.