mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 11:36:44 +00:00
Allow reload of plugin registry when config changes (#5662)
* Allow reload of plugin registry when config changes - Any global settings which control plugin behaviour trigger reload - Plugin registry hash includes the value of these settings - Plugin registry hash is now cached * typo
This commit is contained in:
parent
4b13f3b0de
commit
a6dbe185c6
@ -951,6 +951,16 @@ def update_exchange_rates(setting):
|
|||||||
InvenTree.tasks.update_exchange_rates()
|
InvenTree.tasks.update_exchange_rates()
|
||||||
|
|
||||||
|
|
||||||
|
def reload_plugin_registry(setting):
|
||||||
|
"""When a core plugin setting is changed, reload the plugin registry"""
|
||||||
|
|
||||||
|
from plugin import registry
|
||||||
|
|
||||||
|
logger.info("Reloading plugin registry due to change in setting '%s'", setting.key)
|
||||||
|
|
||||||
|
registry.reload_plugins(full_reload=True, force_reload=True, collect=True)
|
||||||
|
|
||||||
|
|
||||||
class InvenTreeSetting(BaseInvenTreeSetting):
|
class InvenTreeSetting(BaseInvenTreeSetting):
|
||||||
"""An InvenTreeSetting object is a key:value pair used for storing single values (e.g. one-off settings values).
|
"""An InvenTreeSetting object is a key:value pair used for storing single values (e.g. one-off settings values).
|
||||||
|
|
||||||
@ -1704,7 +1714,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
|||||||
'description': _('Enable plugins to add URL routes'),
|
'description': _('Enable plugins to add URL routes'),
|
||||||
'default': False,
|
'default': False,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
'requires_restart': True,
|
'after_save': reload_plugin_registry,
|
||||||
},
|
},
|
||||||
|
|
||||||
'ENABLE_PLUGINS_NAVIGATION': {
|
'ENABLE_PLUGINS_NAVIGATION': {
|
||||||
@ -1712,7 +1722,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
|||||||
'description': _('Enable plugins to integrate into navigation'),
|
'description': _('Enable plugins to integrate into navigation'),
|
||||||
'default': False,
|
'default': False,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
'requires_restart': True,
|
'after_save': reload_plugin_registry,
|
||||||
},
|
},
|
||||||
|
|
||||||
'ENABLE_PLUGINS_APP': {
|
'ENABLE_PLUGINS_APP': {
|
||||||
@ -1720,7 +1730,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
|||||||
'description': _('Enable plugins to add apps'),
|
'description': _('Enable plugins to add apps'),
|
||||||
'default': False,
|
'default': False,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
'requires_restart': True,
|
'after_save': reload_plugin_registry,
|
||||||
},
|
},
|
||||||
|
|
||||||
'ENABLE_PLUGINS_SCHEDULE': {
|
'ENABLE_PLUGINS_SCHEDULE': {
|
||||||
@ -1728,7 +1738,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
|||||||
'description': _('Enable plugins to run scheduled tasks'),
|
'description': _('Enable plugins to run scheduled tasks'),
|
||||||
'default': False,
|
'default': False,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
'requires_restart': True,
|
'after_save': reload_plugin_registry,
|
||||||
},
|
},
|
||||||
|
|
||||||
'ENABLE_PLUGINS_EVENTS': {
|
'ENABLE_PLUGINS_EVENTS': {
|
||||||
@ -1736,7 +1746,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
|||||||
'description': _('Enable plugins to respond to internal events'),
|
'description': _('Enable plugins to respond to internal events'),
|
||||||
'default': False,
|
'default': False,
|
||||||
'validator': bool,
|
'validator': bool,
|
||||||
'requires_restart': True,
|
'after_save': reload_plugin_registry,
|
||||||
},
|
},
|
||||||
|
|
||||||
"PROJECT_CODES_ENABLED": {
|
"PROJECT_CODES_ENABLED": {
|
||||||
|
@ -56,7 +56,7 @@ class ScheduleMixin:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _activate_mixin(cls, registry, plugins, *args, **kwargs):
|
def _activate_mixin(cls, registry, plugins, *args, **kwargs):
|
||||||
"""Activate scheudles from plugins with the ScheduleMixin."""
|
"""Activate schedules from plugins with the ScheduleMixin."""
|
||||||
logger.debug('Activating plugin tasks')
|
logger.debug('Activating plugin tasks')
|
||||||
|
|
||||||
from common.models import InvenTreeSetting
|
from common.models import InvenTreeSetting
|
||||||
|
@ -54,6 +54,9 @@ class PluginsRegistry:
|
|||||||
self.plugins_inactive: Dict[str, InvenTreePlugin] = {} # List of inactive instances
|
self.plugins_inactive: Dict[str, InvenTreePlugin] = {} # List of inactive instances
|
||||||
self.plugins_full: Dict[str, InvenTreePlugin] = {} # List of all plugin instances
|
self.plugins_full: Dict[str, InvenTreePlugin] = {} # List of all plugin instances
|
||||||
|
|
||||||
|
# Keep an internal hash of the plugin registry state
|
||||||
|
self.registry_hash = None
|
||||||
|
|
||||||
self.plugin_modules: List[InvenTreePlugin] = [] # Holds all discovered plugins
|
self.plugin_modules: List[InvenTreePlugin] = [] # Holds all discovered plugins
|
||||||
self.mixin_modules: Dict[str, Any] = {} # Holds all discovered mixins
|
self.mixin_modules: Dict[str, Any] = {} # Holds all discovered mixins
|
||||||
|
|
||||||
@ -633,17 +636,17 @@ class PluginsRegistry:
|
|||||||
|
|
||||||
from common.models import InvenTreeSetting
|
from common.models import InvenTreeSetting
|
||||||
|
|
||||||
plg_hash = self.calculate_plugin_hash()
|
self.registry_hash = self.calculate_plugin_hash()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
old_hash = InvenTreeSetting.get_setting("_PLUGIN_REGISTRY_HASH", "", create=False, cache=False)
|
old_hash = InvenTreeSetting.get_setting("_PLUGIN_REGISTRY_HASH", "", create=False, cache=False)
|
||||||
except Exception:
|
except Exception:
|
||||||
old_hash = ""
|
old_hash = ""
|
||||||
|
|
||||||
if old_hash != plg_hash:
|
if old_hash != self.registry_hash:
|
||||||
try:
|
try:
|
||||||
logger.debug("Updating plugin registry hash: %s", str(plg_hash))
|
logger.debug("Updating plugin registry hash: %s", str(self.registry_hash))
|
||||||
InvenTreeSetting.set_setting("_PLUGIN_REGISTRY_HASH", plg_hash, change_user=None)
|
InvenTreeSetting.set_setting("_PLUGIN_REGISTRY_HASH", self.registry_hash, change_user=None)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.exception("Failed to update plugin registry hash: %s", str(exc))
|
logger.exception("Failed to update plugin registry hash: %s", str(exc))
|
||||||
|
|
||||||
@ -656,6 +659,8 @@ class PluginsRegistry:
|
|||||||
|
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
|
||||||
|
from common.models import InvenTreeSetting
|
||||||
|
|
||||||
data = md5()
|
data = md5()
|
||||||
|
|
||||||
# Hash for all loaded plugins
|
# Hash for all loaded plugins
|
||||||
@ -664,6 +669,21 @@ class PluginsRegistry:
|
|||||||
data.update(str(plug.version).encode())
|
data.update(str(plug.version).encode())
|
||||||
data.update(str(plug.is_active()).encode())
|
data.update(str(plug.is_active()).encode())
|
||||||
|
|
||||||
|
# Also hash for all config settings which define plugin behavior
|
||||||
|
keys = [
|
||||||
|
'ENABLE_PLUGINS_URL',
|
||||||
|
'ENABLE_PLUGINS_NAVIGATION',
|
||||||
|
'ENABLE_PLUGINS_APP',
|
||||||
|
'ENABLE_PLUGINS_SCHEDULE',
|
||||||
|
'ENABLE_PLUGINS_EVENTS'
|
||||||
|
]
|
||||||
|
|
||||||
|
for k in keys:
|
||||||
|
try:
|
||||||
|
data.update(str(InvenTreeSetting.get_setting(k, False, cache=False, create=False)).encode())
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
return str(data.hexdigest())
|
return str(data.hexdigest())
|
||||||
|
|
||||||
def check_reload(self):
|
def check_reload(self):
|
||||||
@ -677,13 +697,17 @@ class PluginsRegistry:
|
|||||||
|
|
||||||
logger.debug("Checking plugin registry hash")
|
logger.debug("Checking plugin registry hash")
|
||||||
|
|
||||||
|
# If not already cached, calculate the hash
|
||||||
|
if not self.registry_hash:
|
||||||
|
self.registry_hash = self.calculate_plugin_hash()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
reg_hash = InvenTreeSetting.get_setting("_PLUGIN_REGISTRY_HASH", "", create=False, cache=False)
|
reg_hash = InvenTreeSetting.get_setting("_PLUGIN_REGISTRY_HASH", "", create=False, cache=False)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
logger.exception("Failed to retrieve plugin registry hash: %s", str(exc))
|
logger.exception("Failed to retrieve plugin registry hash: %s", str(exc))
|
||||||
return
|
return
|
||||||
|
|
||||||
if reg_hash and reg_hash != self.calculate_plugin_hash():
|
if reg_hash and reg_hash != self.registry_hash:
|
||||||
logger.info("Plugin registry hash has changed - reloading")
|
logger.info("Plugin registry hash has changed - reloading")
|
||||||
self.reload_plugins(full_reload=True, force_reload=True, collect=True)
|
self.reload_plugins(full_reload=True, force_reload=True, collect=True)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user