0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-12-01 11:41:20 +01:00

Use multiple threads for rendition generation

This commit is contained in:
Andy Babic 2022-12-05 14:10:17 +00:00 committed by zerolab
parent 6e604cb278
commit 3a8dbd0a28
No known key found for this signature in database

View File

@ -3,6 +3,7 @@ import logging
import os.path
import time
from collections import OrderedDict, defaultdict
from concurrent.futures import ThreadPoolExecutor
from contextlib import contextmanager
from tempfile import SpooledTemporaryFile
from io import BytesIO
@ -645,14 +646,14 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
filter_map: Dict[str, Filter] = {f.spec: f for f in filters}
with self.open_file() as file:
in_memory_file = ContentFile(file.read(), name=self.file.name)
original_image_bytes = file.read()
to_create = []
for filter in filters:
image_file = self.generate_rendition_file(filter, source=in_memory_file)
# Reset in-memory file for next use
in_memory_file.seek(0)
# Add for bulk creation
def _generate_single_rendition(filter):
image_file = self.generate_rendition_file(
filter, source=ContentFile(original_image_bytes, name=self.file.name)
)
to_create.append(
Rendition(
image=self,
@ -662,6 +663,9 @@ class AbstractImage(ImageFileMixin, CollectionMember, index.Indexed, models.Mode
)
)
with ThreadPoolExecutor() as executor:
executor.map(_generate_single_rendition, filters)
# Rendition generation can take a while. So, if other processes have created
# identical renditions in the meantime, we should find them to avoid clashes.
# NB: Clashes can still occur, because there is no get_or_create() equivalent