mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Let plugins decide if events should be processed or not (#5618)
* add wants_process_event to EventMixin in register_event this function get called and the task is just offload if the plugin returns true * add tests for wants_process_event * fix comments for register_event after code changes * add documentation for EventMixin.wants_process_event * avoid pre-formatting log messages --------- Co-authored-by: Oliver Lippert <oliver@lipperts-web.de>
This commit is contained in:
parent
7fa0c6d280
commit
46b0d77418
@ -65,11 +65,16 @@ def register_event(event, *args, **kwargs):
|
||||
with transaction.atomic():
|
||||
|
||||
for slug, plugin in registry.plugins.items():
|
||||
if not plugin.mixin_enabled('events'):
|
||||
continue
|
||||
|
||||
if plugin.mixin_enabled('events'):
|
||||
|
||||
if plugin.is_active():
|
||||
# Only allow event registering for 'active' plugins
|
||||
if not plugin.is_active():
|
||||
continue
|
||||
|
||||
# Let the plugin decide if it wants to process this event
|
||||
if not plugin.wants_process_event(event):
|
||||
continue
|
||||
|
||||
logger.debug("Registering callback for plugin '%s'", slug)
|
||||
|
||||
|
@ -9,6 +9,15 @@ class EventMixin:
|
||||
Implementing classes must provide a "process_event" function:
|
||||
"""
|
||||
|
||||
def wants_process_event(self, event):
|
||||
"""Function to subscribe to events.
|
||||
|
||||
Return true if you're interested in the given event, false if not.
|
||||
"""
|
||||
|
||||
# Default implementation always returns true (backwards compatibility)
|
||||
return True
|
||||
|
||||
def process_event(self, event, *args, **kwargs):
|
||||
"""Function to handle events.
|
||||
|
||||
|
32
InvenTree/plugin/samples/event/filtered_event_sample.py
Normal file
32
InvenTree/plugin/samples/event/filtered_event_sample.py
Normal file
@ -0,0 +1,32 @@
|
||||
"""Sample plugin which responds to events."""
|
||||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.mixins import EventMixin
|
||||
|
||||
logger = logging.getLogger('inventree')
|
||||
|
||||
|
||||
class FilteredEventPluginSample(EventMixin, InvenTreePlugin):
|
||||
"""A sample plugin which provides supports for triggered events."""
|
||||
|
||||
NAME = "FilteredEventPlugin"
|
||||
SLUG = "filteredsampleevent"
|
||||
TITLE = "Triggered by test.event only"
|
||||
|
||||
def wants_process_event(self, event):
|
||||
"""Return whether given event should be processed or not."""
|
||||
return event == "test.event"
|
||||
|
||||
def process_event(self, event, *args, **kwargs):
|
||||
"""Custom event processing."""
|
||||
print(f"Processing triggered event: '{event}'")
|
||||
print("args:", str(args))
|
||||
print("kwargs:", str(kwargs))
|
||||
|
||||
# Issue warning that we can test for
|
||||
if settings.PLUGIN_TESTING:
|
||||
logger.debug('Event `%s` triggered in sample plugin', event)
|
52
InvenTree/plugin/samples/event/test_filtered_event_sample.py
Normal file
52
InvenTree/plugin/samples/event/test_filtered_event_sample.py
Normal file
@ -0,0 +1,52 @@
|
||||
"""Unit tests for event_sample sample plugins."""
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
|
||||
from common.models import InvenTreeSetting
|
||||
from plugin import registry
|
||||
from plugin.base.event.events import trigger_event
|
||||
|
||||
from .filtered_event_sample import logger
|
||||
|
||||
|
||||
class FilteredEventPluginSampleTests(TestCase):
|
||||
"""Tests for EventPluginSample."""
|
||||
|
||||
def test_run_event(self):
|
||||
"""Check if the event is issued."""
|
||||
# Activate plugin
|
||||
config = registry.get_plugin('filteredsampleevent').plugin_config()
|
||||
config.active = True
|
||||
config.save()
|
||||
|
||||
InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None)
|
||||
|
||||
# Enable event testing
|
||||
settings.PLUGIN_TESTING_EVENTS = True
|
||||
# Check that an event is issued
|
||||
with self.assertLogs(logger=logger, level="DEBUG") as cm:
|
||||
trigger_event('test.event')
|
||||
self.assertIn('DEBUG:inventree:Event `test.event` triggered in sample plugin', cm[1])
|
||||
|
||||
# Disable again
|
||||
settings.PLUGIN_TESTING_EVENTS = False
|
||||
|
||||
def test_ignore_event(self):
|
||||
"""Check if the event is issued."""
|
||||
# Activate plugin
|
||||
config = registry.get_plugin('filteredsampleevent').plugin_config()
|
||||
config.active = True
|
||||
config.save()
|
||||
|
||||
InvenTreeSetting.set_setting('ENABLE_PLUGINS_EVENTS', True, change_user=None)
|
||||
|
||||
# Enable event testing
|
||||
settings.PLUGIN_TESTING_EVENTS = True
|
||||
# Check that an event is issued
|
||||
with self.assertLogs(logger=logger, level="DEBUG") as cm:
|
||||
trigger_event('test.some.other.event')
|
||||
self.assertNotIn('DEBUG:inventree:Event `test.some.other.event` triggered in sample plugin', cm[1])
|
||||
|
||||
# Disable again
|
||||
settings.PLUGIN_TESTING_EVENTS = False
|
@ -15,9 +15,9 @@ When a certain (server-side) event occurs, the background worker passes the even
|
||||
{% include 'img.html' %}
|
||||
{% endwith %}
|
||||
|
||||
### Example
|
||||
### Example (all events)
|
||||
|
||||
Implementing classes must provide a `process_event` function:
|
||||
Implementing classes must at least provide a `process_event` function:
|
||||
|
||||
```python
|
||||
class EventPlugin(EventMixin, InvenTreePlugin):
|
||||
@ -36,6 +36,34 @@ class EventPlugin(EventMixin, InvenTreePlugin):
|
||||
print(f"Processing triggered event: '{event}'")
|
||||
```
|
||||
|
||||
### Example (specific events)
|
||||
|
||||
If you want to process just some specific events, you can also implement the `wants_process_event` function to decide if you want to process this event or not. This function will be executed synchronously, so be aware that it should contain simple logic.
|
||||
|
||||
Overall this function can reduce the workload on the background workers significantly since less events are queued to be processed.
|
||||
|
||||
```python
|
||||
class EventPlugin(EventMixin, InvenTreePlugin):
|
||||
"""
|
||||
A simple example plugin which responds to 'salesordershipment.completed' event on the InvenTree server.
|
||||
|
||||
This example simply prints out the event information.
|
||||
A more complex plugin can run enhanced logic on this event.
|
||||
"""
|
||||
|
||||
NAME = "EventPlugin"
|
||||
SLUG = "event"
|
||||
TITLE = "Triggered Events"
|
||||
|
||||
def wants_process_event(self, event):
|
||||
"""Here you can decide if this event should be send to `process_event` or not."""
|
||||
return event == "salesordershipment.completed"
|
||||
|
||||
def process_event(self, event, *args, **kwargs):
|
||||
"""Here you can run you'r specific logic."""
|
||||
print(f"Sales order was completely shipped: '{args}' '{kwargs}'")
|
||||
```
|
||||
|
||||
### Events
|
||||
|
||||
Events are passed through using a string identifier, e.g. `build.completed`
|
||||
|
Loading…
Reference in New Issue
Block a user