Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump pillow from 9.5.0 to 10.0.1 #5657

Merged
merged 9 commits into from
Nov 6, 2023
44 changes: 33 additions & 11 deletions InvenTree/InvenTree/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,13 @@ def record_task_success(task_name: str):
InvenTreeSetting.set_setting(f'_{task_name}_SUCCESS', datetime.now().isoformat(), None)


def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs):
def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs) -> bool:
"""Create an AsyncTask if workers are running. This is different to a 'scheduled' task, in that it only runs once!

If workers are not running or force_sync flag
is set then the task is ran synchronously.
If workers are not running or force_sync flag, is set then the task is ran synchronously.

Returns:
bool: True if the task was offloaded (or ran), False otherwise
"""
try:
import importlib
Expand All @@ -173,19 +175,32 @@ def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs)
from InvenTree.status import is_worker_running
except AppRegistryNotReady: # pragma: no cover
logger.warning("Could not offload task '%s' - app registry not ready", taskname)
return

if force_async:
# Cannot async the task, so return False
return False
else:
force_sync = True
except (OperationalError, ProgrammingError): # pragma: no cover
raise_warning(f"Could not offload task '{taskname}' - database not ready")

if force_async:
# Cannot async the task, so return False
return False
else:
force_sync = True

if force_async or (is_worker_running() and not force_sync):
# Running as asynchronous task
try:
task = AsyncTask(taskname, *args, **kwargs)
task.run()
except ImportError:
raise_warning(f"WARNING: '{taskname}' not started - Function not found")
raise_warning(f"WARNING: '{taskname}' not offloaded - Function not found")
return False
except Exception as exc:
raise_warning(f"WARNING: '{taskname}' not started due to {type(exc)}")
raise_warning(f"WARNING: '{taskname}' not offloaded due to {str(exc)}")
return False
else:

if callable(taskname):
Expand All @@ -198,14 +213,14 @@ def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs)
app_mod = app + '.' + mod
except ValueError:
raise_warning(f"WARNING: '{taskname}' not started - Malformed function path")
return
return False

# Import module from app
try:
_mod = importlib.import_module(app_mod)
except ModuleNotFoundError:
raise_warning(f"WARNING: '{taskname}' not started - No module named '{app_mod}'")
return
return False

# Retrieve function
try:
Expand All @@ -219,10 +234,17 @@ def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs)
_func = eval(func) # pragma: no cover
except NameError:
raise_warning(f"WARNING: '{taskname}' not started - No function named '{func}'")
return
return False

# Workers are not running: run it as synchronous task
_func(*args, **kwargs)
try:
_func(*args, **kwargs)
except Exception as exc:
raise_warning(f"WARNING: '{taskname}' not started due to {str(exc)}")
return False

# Finally, task either completed successfully or was offloaded
return True


@dataclass()
Expand All @@ -249,7 +271,7 @@ class ScheduledTask:


class TaskRegister:
"""Registry for periodicall tasks."""
"""Registry for periodic tasks."""
task_list: List[ScheduledTask] = []

def register(self, task, schedule, minutes: int = None):
Expand Down
34 changes: 24 additions & 10 deletions InvenTree/InvenTree/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1095,25 +1095,39 @@ def test_offload_tasks(self):

Ref: https://github.com/inventree/InvenTree/pull/3273
"""
offload_task(
'dummy_tasks.parts',
part=Part.objects.get(pk=1),
cat=PartCategory.objects.get(pk=1),
force_async=True
)

offload_task(
self.assertTrue(offload_task(
'dummy_tasks.stock',
item=StockItem.objects.get(pk=1),
loc=StockLocation.objects.get(pk=1),
force_async=True
)
))

offload_task(
self.assertTrue(offload_task(
'dummy_task.numbers',
1, 2, 3, 4, 5,
force_async=True
)
))

# Offload a dummy task, but force sync
# This should fail, because the function does not exist
with self.assertLogs(logger='inventree', level='WARNING') as log:
self.assertFalse(offload_task(
'dummy_task.numbers',
1, 1, 1,
force_sync=True
))

self.assertIn("Malformed function path", str(log.output))

# Offload dummy task with a Part instance
# This should succeed, ensuring that the Part instance is correctly pickled
self.assertTrue(offload_task(
'dummy_tasks.parts',
part=Part.objects.get(pk=1),
cat=PartCategory.objects.get(pk=1),
force_async=True
))

def test_daily_holdoff(self):
"""Tests for daily task holdoff helper functions"""
Expand Down
4 changes: 2 additions & 2 deletions requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ django-q-sentry # sentry.io integration for django-q
django-sesame # Magic link authentication
django-sql-utils # Advanced query annotation / aggregation
django-sslserver # Secure HTTP development server
django-stdimage<6.0.0 # Advanced ImageField management # FIXED 2022-06-29 6.0.0 breaks serialization for django-q
django-stdimage # Advanced ImageField management
django-taggit # Tagging support
django-user-sessions # user sessions in DB
django-weasyprint # django weasyprint integration
Expand All @@ -37,7 +37,7 @@ drf-spectacular # DRF API documentation
feedparser # RSS newsfeed parser
gunicorn # Gunicorn web server
pdf2image # PDF to image conversion
pillow==9.5.0 # Image manipulation # FIXED 2023-07-04 as we require PIL.Image.ANTIALIAS
pillow # Image manipulation

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SchrodingersGat Unfortunately this line change breaks the inventree-brother-plugin due to brother_ql needing a fix seen in pklaus/brother_ql#143. Any suggestions on how to get this back to working?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atanisoft we are using a fork of brother_ql - https://github.com/matmair/brother_ql-inventree so we can just update that

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be great if that could be updated, can a new version be pushed for both to pick up that fix?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New version is released, 1.1 includes the fix and seems to work

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, after shutting down and starting up the docker containers it seems to have fixed it with the newer version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atanisoft good to hear! And @matmair thanks for the quick fix

pint==0.21 # Unit conversion # FIXED 2023-05-30 breaks tests https://github.com/matmair/InvenTree/actions/runs/5095665936/jobs/9160852560
python-barcode[images] # Barcode generator
python-dotenv # Environment variable management
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ django-sql-utils==0.7.0
# via -r requirements.in
django-sslserver==0.22
# via -r requirements.in
django-stdimage==5.3.0
django-stdimage==6.0.2
# via -r requirements.in
django-taggit==4.0.0
# via -r requirements.in
Expand Down Expand Up @@ -201,7 +201,7 @@ packaging==23.2
# via gunicorn
pdf2image==1.16.3
# via -r requirements.in
pillow==9.5.0
pillow==10.1.0
# via
# -r requirements.in
# django-stdimage
Expand Down
Loading