Fixes the way threading works

This commit is contained in:
2025-08-02 14:01:00 -06:00
parent 83ad521fea
commit 1f7a3e3d36
2 changed files with 26 additions and 35 deletions

View File

@@ -5,7 +5,7 @@ import logging.handlers
import argparse
from abc import ABC, abstractmethod
from datetime import datetime
from threading import Lock
from threading import Lock, Condition
import bisect
import time
import re
@@ -102,9 +102,9 @@ class ImageRepo(ABC):
self._data_loaded = False
"""A flag for when the data has been successfully loaded."""
self._load_lock = Lock()
self._load_lock = Condition(Lock())
"""A lock for enforcing thread safety when loading this repository."""
self._download_lock = Lock()
self._download_lock = Condition(Lock())
"""A lock for enforcing thread safety when downloading secondary resources."""
def get_identifier_string(self):
@@ -122,7 +122,7 @@ class ImageRepo(ABC):
:returns: True if the data has been fully loaded, false otherwise.
"""
return not self._load_lock.locked() and self._data_loaded
return not self._load_lock._lock.locked() and self._data_loaded
def is_downloaded(self):
"""
@@ -130,7 +130,7 @@ class ImageRepo(ABC):
:returns: True if the images have been fully downloaded, false otherwise.
"""
return not self.image_urls or (not self._download_lock.locked() and self.images)
return not self.image_urls or (not self._download_lock._lock.locked() and self.images)
def load_data(self):
"""
@@ -147,12 +147,12 @@ class ImageRepo(ABC):
:see: #await_load
:see: #_load_data
"""
if not self._load_lock.locked() and not self._data_loaded:
if self._load_lock.acquire():
with self._load_lock:
if not self._data_loaded:
self._load_data()
logging.info("Completed loading of %s", self.get_identifier_string())
self._data_loaded = True
self._load_lock.release()
self._load_lock.notify_all()
def await_load(self):
"""
@@ -162,12 +162,8 @@ class ImageRepo(ABC):
:see: #load_data
"""
if self._load_lock.locked():
self._load_lock.acquire()
self._load_lock.release()
else:
# Loads this ourselves
self.load_data()
# Loads this ourselves
self.load_data()
@abstractmethod
@@ -200,12 +196,13 @@ class ImageRepo(ABC):
if not self.is_loaded():
raise SequenceException("Cannot download images before first loading performed.")
# Checks to see if we need to download and that one is not already in progress
if not self._download_lock.locked() and self.image_urls and not self.images:
if self._download_lock.acquire():
with self._download_lock:
# Checks to see if we need to download and that one is not already in progress
if self.image_urls and not self.images:
logging.info("Downloading %s", self.get_identifier_string())
self._download_data()
logging.info("Completed downloading of %s", self.get_identifier_string())
self._download_lock.release()
self._download_lock.notify_all()
def await_download(self):
"""
@@ -215,12 +212,7 @@ class ImageRepo(ABC):
:see: #download_data
"""
if self._download_lock.locked():
self._download_lock.acquire()
self._download_lock.release()
else:
# Downloads this ourselves
self.download_data()
self.download_data()
def _download_data(self):
"""
@@ -346,7 +338,7 @@ class ComicStrip(ImageRepo, ABC):
"""A list of captions for each panel."""
self.date = None
"""The date that the comic was published."""
self._transform_lock = Lock()
self._transform_lock = Condition(Lock())
"""A lock for enforcing thread safety when transforming resources."""
self.transformed_images = []
"""A list of NamedTemporaryFiles linking to the transformed versions of the image downloads."""
@@ -438,21 +430,20 @@ class ComicStrip(ImageRepo, ABC):
if not self.is_downloaded():
raise SequenceException("Cannot package comic strip before strip data has been fully downloaded.")
if not self.comic.is_loaded():
raise SequenceException("Cannot package comic before data has been fully loaded.")
raise SequenceException("Cannot package comic strip before comic data has been fully loaded.")
if not self.comic.is_downloaded():
raise SequenceException("Cannot package comic before data has been fully downloaded.")
raise SequenceException("Cannot package comic strip before comic data has been fully downloaded.")
if not self.transformed_images:
if not self._transformed:
if self._transform_lock.locked():
if self._transform_lock._lock.locked():
# Await for the existing transform to complete
self._transform_lock.acquire()
self._transform_lock.release()
self._transform_lock.wait()
else:
# Run the transformation outselves
self._transform_lock.acquire()
self._transform_images()
self._transformed = True
self._transform_lock.release()
with self._transform_lock:
self._transform_images()
self._transformed = True
self._transform_lock.notify_all()
with ZipFile(self.get_package_path(base_path), 'w') as comic_zip:
for i in range(len(self.transformed_images)):
image = self.transformed_images[i]