From d765be8c73177214bca23cf63f843a2e494f1074 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 9 Jan 2022 22:58:59 +1100 Subject: [PATCH] Iterate through plugins in a separate background task --- InvenTree/build/models.py | 20 ++++++++ .../plugin/builtin/integration/mixins.py | 2 +- InvenTree/plugin/events.py | 46 +++++++++++++------ InvenTree/plugin/integration.py | 2 +- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index f03cb30c74..30f80d8aa1 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -36,6 +36,8 @@ import InvenTree.fields import InvenTree.helpers import InvenTree.tasks +from plugin.events import trigger_event + from part import models as PartModels from stock import models as StockModels from users import models as UserModels @@ -585,6 +587,13 @@ class Build(MPTTModel, ReferenceIndexingMixin): # which point to thie Build Order self.allocated_stock.all().delete() + # Register an event + trigger_event( + 'build.completed', + build_id=self.pk, + user_id=user.pk, + ) + @transaction.atomic def cancelBuild(self, user): """ Mark the Build as CANCELLED @@ -604,6 +613,12 @@ class Build(MPTTModel, ReferenceIndexingMixin): self.status = BuildStatus.CANCELLED self.save() + trigger_event( + 'build.cancelled', + build_id=self.pk, + user_id=user.pk, + ) + @transaction.atomic def unallocateStock(self, bom_item=None, output=None): """ @@ -1042,6 +1057,11 @@ def after_save_build(sender, instance: Build, created: bool, **kwargs): # Run checks on required parts InvenTree.tasks.offload_task('build.tasks.check_build_stock', instance) + trigger_event( + 'build.created', + build_id=instance.pk, + ) + class BuildOrderAttachment(InvenTreeAttachment): """ diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index 6354ca3973..cf15acdef9 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -191,7 +191,7 @@ class EventMixin: def process_event(self, event, *args, **kwargs): # Default implementation does not do anything raise NotImplementedError - + class MixinMeta: MIXIN_NAME = 'Events' diff --git a/InvenTree/plugin/events.py b/InvenTree/plugin/events.py index 49f5a87c6f..6589a6f601 100644 --- a/InvenTree/plugin/events.py +++ b/InvenTree/plugin/events.py @@ -30,27 +30,47 @@ def trigger_event(event, *args, **kwargs): logger.debug(f"Event triggered: '{event}'") - # Offload a separate task for each plugin + offload_task( + 'plugin.event.register_event', + event, + *args, + **kwargs + ) + + +def register_event(event, *args, **kwargs): + """ + Register the event with any interested plugins. + + Note: This function is processed by the background worker, + as it performs multiple database access operations. + """ + + logger.debug(f"Registering triggered event: '{event}'") + # Determine if there are any plugins which are interested in responding if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_EVENTS'): - for slug, plugin in plugin_registry.plugins.items(): + with transaction.atomic(): - if plugin.mixin_enabled('events'): + for slug, plugin in plugin_registry.plugins.items(): - config = plugin.plugin_config() + if plugin.mixin_enabled('events'): - if config and config.active: + config = plugin.plugin_config() - logger.debug(f"Registering callback for plugin '{slug}'") + if config and config.active: - offload_task( - 'plugin.events.process_event', - slug, - event, - *args, - **kwargs - ) + logger.debug(f"Registering callback for plugin '{slug}'") + + # Offload a separate task for each plugin + offload_task( + 'plugin.events.process_event', + slug, + event, + *args, + **kwargs + ) def process_event(plugin_slug, event, *args, **kwargs): diff --git a/InvenTree/plugin/integration.py b/InvenTree/plugin/integration.py index c012336a7a..c00b81419d 100644 --- a/InvenTree/plugin/integration.py +++ b/InvenTree/plugin/integration.py @@ -178,7 +178,7 @@ class IntegrationPluginBase(MixinBase, plugin.InvenTreePlugin): fnc_name = self._mixins.get(key) # Allow for simple case where the mixin is "always" ready - if fnc_name == True: + if fnc_name is True: return True return getattr(self, fnc_name, True)