Scheduled tasks get registered for the background worker

This commit is contained in:
Oliver Walters 2022-01-07 16:51:00 +11:00
parent ff598a22ff
commit 3eb1fa32f9
3 changed files with 110 additions and 5 deletions

View File

@ -2,6 +2,8 @@
Plugin mixin classes
"""
import logging
from django.conf.urls import url, include
from django.db.utils import OperationalError, ProgrammingError
@ -9,6 +11,9 @@ from plugin.models import PluginConfig, PluginSetting
from plugin.urls import PLUGIN_BASE
logger = logging.getLogger('inventree')
class SettingsMixin:
"""
Mixin that enables global settings for the plugin
@ -116,6 +121,58 @@ class ScheduleMixin:
if schedule == 'I' and 'minutes' not in task:
raise ValueError(f"Task '{key}' is missing 'minutes' parameter")
def get_task_name(self, key):
# Generate a 'unique' task name
slug = self.plugin_slug()
return f"plugin.{slug}.{key}"
def get_task_names(self):
# Returns a list of all task names associated with this plugin instance
return [self.get_task_name(key) for key in self.scheduled_tasks.keys()]
def register_tasks(self):
"""
Register the tasks with the database
"""
from django_q.models import Schedule
for key, task in self.scheduled_tasks.items():
task_name = self.get_task_name(key)
# If a matching scheduled task does not exist, create it!
if not Schedule.objects.filter(name=task_name).exists():
logger.info(f"Adding scheduled task '{task_name}'")
Schedule.objects.create(
name=task_name,
func=task['func'],
schedule_type=task['schedule'],
minutes=task.get('minutes', None),
repeats=task.get('repeats', -1),
)
def unregister_tasks(self):
"""
Deregister the tasks with the database
"""
from django_q.models import Schedule
for key, task in self.scheduled_tasks.items():
task_name = self.get_task_name(key)
try:
scheduled_task = Schedule.objects.get(name=task_name)
scheduled_task.delete()
except Schedule.DoesNotExist:
pass
class UrlsMixin:
"""
Mixin that enables custom URLs for the plugin

View File

@ -262,18 +262,21 @@ class PluginsRegistry:
logger.info(f'Found {len(plugins)} active plugins')
self.activate_integration_settings(plugins)
self.activate_integration_schedule(plugins)
self.activate_integration_app(plugins, force_reload=force_reload)
def _deactivate_plugins(self):
"""
Run integration deactivation functions for all plugins
"""
self.deactivate_integration_app()
self.deactivate_integration_schedule()
self.deactivate_integration_settings()
def activate_integration_settings(self, plugins):
logger.info('Registering IntegrationPlugin global settings')
logger.info('Activating plugin settings')
self.mixins_settings = {}
@ -293,8 +296,50 @@ class PluginsRegistry:
# clear cache
self.mixins_settings = {}
def activate_integration_schedule(self, plugins):
logger.info('Activating plugin tasks')
from common.models import InvenTreeSetting
from django_q.models import Schedule
# List of tasks we have activated
task_keys = []
if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_SCHEDULE'):
for slug, plugin in plugins:
if plugin.mixin_enabled('schedule'):
config = plugin.plugin_config()
# Only active tasks for plugins which are enabled
if config and config.active:
plugin.register_tasks()
task_keys += plugin.get_task_names()
logger.info(f"Activated {len(task_keys)} scheduled tasks")
# Remove any scheduled tasks which do not match
# This stops 'old' plugin tasks from accumulating
scheduled_plugin_tasks = Schedule.objects.filter(name__istartswith="plugin.")
deleted_count = 0
for task in scheduled_plugin_tasks:
if task.name not in task_keys:
task.delete()
deleted_count += 1
if deleted_count > 0:
logger.info(f"Removed {deleted_count} old scheduled tasks")
def deactivate_integration_schedule(self):
pass
def activate_integration_app(self, plugins, force_reload=False):
"""activate AppMixin plugins - add custom apps and reload
"""
Activate AppMixin plugins - add custom apps and reload
:param plugins: list of IntegrationPlugins that should be installed
:type plugins: dict
@ -378,7 +423,10 @@ class PluginsRegistry:
return plugin_path
def deactivate_integration_app(self):
"""deactivate integration app - some magic required"""
"""
Deactivate integration app - some magic required
"""
# unregister models from admin
for plugin_path in self.installed_apps:
models = [] # the modelrefs need to be collected as poping an item in a iter is not welcomed

View File

@ -26,12 +26,12 @@ class ScheduledTaskPlugin(ScheduleMixin, IntegrationPluginBase):
SCHEDULED_TASKS = {
'hello': {
'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_hello',
'func': 'plugin.samples.integration.scheduled_task.print_hello',
'schedule': 'I',
'minutes': 5,
},
'world': {
'func': 'plugin.builtin.integration.mixins.ScheduleMixin.print_world',
'func': 'plugin.samples.integration.scheduled_task.print_hello',
'schedule': 'H',
}
}