From c1064906d622bb951dede3d5802c2a93e28ec4b5 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 17 Oct 2022 23:20:36 +1100 Subject: [PATCH] Revert "Switch to registry for tasks" (#3803) * Revert "Switch to registry for tasks (#3790)" This reverts commit 0bea2c7b561e063dcffe3c867cd244c9041c3e45. * Remove decorator --- InvenTree/InvenTree/apps.py | 68 ++++++++++++++++++++++++++++++----- InvenTree/InvenTree/tasks.py | 70 ------------------------------------ InvenTree/build/tasks.py | 1 - InvenTree/common/tasks.py | 3 -- InvenTree/order/tasks.py | 4 +-- 5 files changed, 61 insertions(+), 85 deletions(-) diff --git a/InvenTree/InvenTree/apps.py b/InvenTree/InvenTree/apps.py index 42b6b55be2..7190197104 100644 --- a/InvenTree/InvenTree/apps.py +++ b/InvenTree/InvenTree/apps.py @@ -54,16 +54,68 @@ class InvenTreeConfig(AppConfig): def start_background_tasks(self): """Start all background tests for InvenTree.""" + try: + from django_q.models import Schedule + except AppRegistryNotReady: # pragma: no cover + logger.warning("Cannot start background tasks - app registry not ready") + return logger.info("Starting background tasks...") - # Run through registered tasks - for task in InvenTree.tasks.tasks.task_list: - InvenTree.tasks.schedule_task( - task.func, - schedule_type=task.interval, - minutes=task.minutes, - ) - logger.info("Started background tasks...") + + # Remove successful task results from the database + InvenTree.tasks.schedule_task( + 'InvenTree.tasks.delete_successful_tasks', + schedule_type=Schedule.DAILY, + ) + + # Check for InvenTree updates + InvenTree.tasks.schedule_task( + 'InvenTree.tasks.check_for_updates', + schedule_type=Schedule.DAILY + ) + + # Heartbeat to let the server know the background worker is running + InvenTree.tasks.schedule_task( + 'InvenTree.tasks.heartbeat', + schedule_type=Schedule.MINUTES, + minutes=15 + ) + + # Keep exchange rates up to date + InvenTree.tasks.schedule_task( + 'InvenTree.tasks.update_exchange_rates', + schedule_type=Schedule.DAILY, + ) + + # Delete old error messages + InvenTree.tasks.schedule_task( + 'InvenTree.tasks.delete_old_error_logs', + schedule_type=Schedule.DAILY, + ) + + # Delete old notification records + InvenTree.tasks.schedule_task( + 'common.tasks.delete_old_notifications', + schedule_type=Schedule.DAILY, + ) + + # Check for overdue purchase orders + InvenTree.tasks.schedule_task( + 'order.tasks.check_overdue_purchase_orders', + schedule_type=Schedule.DAILY + ) + + # Check for overdue sales orders + InvenTree.tasks.schedule_task( + 'order.tasks.check_overdue_sales_orders', + schedule_type=Schedule.DAILY, + ) + + # Check for overdue build orders + InvenTree.tasks.schedule_task( + 'build.tasks.check_overdue_build_orders', + schedule_type=Schedule.DAILY + ) def update_exchange_rates(self): # pragma: no cover """Update exchange rates each time the server is started. diff --git a/InvenTree/InvenTree/tasks.py b/InvenTree/InvenTree/tasks.py index 571b441a5c..43b8caa846 100644 --- a/InvenTree/InvenTree/tasks.py +++ b/InvenTree/InvenTree/tasks.py @@ -4,9 +4,7 @@ import json import logging import re import warnings -from dataclasses import dataclass from datetime import timedelta -from typing import Callable from django.conf import settings from django.core import mail as django_mail @@ -128,69 +126,6 @@ def offload_task(taskname, *args, force_async=False, force_sync=False, **kwargs) _func(*args, **kwargs) -@dataclass() -class ScheduledTask: - """A scheduled task. - - - interval: The interval at which the task should be run - - minutes: The number of minutes between task runs - - func: The function to be run - """ - - func: Callable - interval: str - minutes: int = None - - MINUTES = "I" - HOURLY = "H" - DAILY = "D" - WEEKLY = "W" - MONTHLY = "M" - QUARTERLY = "Q" - YEARLY = "Y" - TYPE = [MINUTES, HOURLY, DAILY, WEEKLY, MONTHLY, QUARTERLY, YEARLY] - - -class TaskRegister: - """Registery for periodicall tasks.""" - task_list: list[ScheduledTask] = [] - - def register(self, task, schedule, minutes: int = None): - """Register a task with the que.""" - self.task_list.append(ScheduledTask(task, schedule, minutes)) - - -tasks = TaskRegister() - - -def scheduled_task(interval: str, minutes: int = None): - """Register the given task as a scheduled task. - - - interval: The interval at which the task should be run - - minutes: The number of minutes between task runs - - Example: - ```python - @register(ScheduledTask.DAILY) - def my_custom_funciton(): - ... - ``` - """ - - def _task_wrapper(admin_class): - if not isinstance(admin_class, Callable): - raise ValueError('Wrapped object must be a function') - - if interval not in ScheduledTask.TYPE: - raise ValueError(f'Invalid interval. Must be one of {ScheduledTask.TYPE}') - - tasks.register(admin_class, interval, minutes=minutes) - - return admin_class - return _task_wrapper - - -@scheduled_task(ScheduledTask.MINUTES, 15) def heartbeat(): """Simple task which runs at 5 minute intervals, so we can determine that the background worker is actually running. @@ -214,7 +149,6 @@ def heartbeat(): heartbeats.delete() -@scheduled_task(ScheduledTask.DAILY) def delete_successful_tasks(): """Delete successful task logs which are more than a month old.""" try: @@ -234,7 +168,6 @@ def delete_successful_tasks(): results.delete() -@scheduled_task(ScheduledTask.DAILY) def delete_old_error_logs(): """Delete old error logs from the server.""" try: @@ -257,7 +190,6 @@ def delete_old_error_logs(): return -@scheduled_task(ScheduledTask.DAILY) def check_for_updates(): """Check if there is an update for InvenTree.""" try: @@ -300,7 +232,6 @@ def check_for_updates(): ) -@scheduled_task(ScheduledTask.DAILY) def update_exchange_rates(): """Update currency exchange rates.""" try: @@ -342,7 +273,6 @@ def update_exchange_rates(): logger.error(f"Error updating exchange rates: {e}") -@scheduled_task(ScheduledTask.DAILY) def run_backup(): """Run the backup command.""" call_command("dbbackup", noinput=True, clean=True, compress=True, interactive=False) diff --git a/InvenTree/build/tasks.py b/InvenTree/build/tasks.py index 6623686155..fcda1f8bff 100644 --- a/InvenTree/build/tasks.py +++ b/InvenTree/build/tasks.py @@ -144,7 +144,6 @@ def notify_overdue_build_order(bo: build.models.Build): trigger_event(event_name, build_order=bo.pk) -@InvenTree.tasks.scheduled_task(InvenTree.tasks.ScheduledTask.DAILY) def check_overdue_build_orders(): """Check if any outstanding BuildOrders have just become overdue diff --git a/InvenTree/common/tasks.py b/InvenTree/common/tasks.py index e600136560..56fd3fb04f 100644 --- a/InvenTree/common/tasks.py +++ b/InvenTree/common/tasks.py @@ -5,12 +5,9 @@ from datetime import datetime, timedelta from django.core.exceptions import AppRegistryNotReady -from InvenTree.tasks import ScheduledTask, scheduled_task - logger = logging.getLogger('inventree') -@scheduled_task(ScheduledTask.DAILY) def delete_old_notifications(): """Remove old notifications from the database. diff --git a/InvenTree/order/tasks.py b/InvenTree/order/tasks.py index 574a732ffb..103fc3cc46 100644 --- a/InvenTree/order/tasks.py +++ b/InvenTree/order/tasks.py @@ -6,13 +6,12 @@ from django.utils.translation import gettext_lazy as _ import common.notifications import InvenTree.helpers +import InvenTree.tasks import order.models from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus -from InvenTree.tasks import ScheduledTask, scheduled_task from plugin.events import trigger_event -@scheduled_task(ScheduledTask.DAILY) def notify_overdue_purchase_order(po: order.models.PurchaseOrder): """Notify users that a PurchaseOrder has just become 'overdue'""" @@ -56,7 +55,6 @@ def notify_overdue_purchase_order(po: order.models.PurchaseOrder): ) -@scheduled_task(ScheduledTask.DAILY) def check_overdue_purchase_orders(): """Check if any outstanding PurchaseOrders have just become overdue: