mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-01 11:10:54 +00:00
[bug] Fixes for plugin loading mechanism (#9826)
* Fix logic for registry mutex lock * Handle potential errors during UsersConfig launch * Remove debug statement * Revert to_raise value * Clear plugin errors on reload * Better method of avoiding duplicates
This commit is contained in:
@ -88,7 +88,7 @@ class PluginsRegistry:
|
|||||||
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
|
||||||
|
|
||||||
self.errors = {} # Holds discovering errors
|
self.errors = {} # Holds errors discovered during loading
|
||||||
|
|
||||||
self.loading_lock = Lock() # Lock to prevent multiple loading at the same time
|
self.loading_lock = Lock() # Lock to prevent multiple loading at the same time
|
||||||
|
|
||||||
@ -307,6 +307,7 @@ class PluginsRegistry:
|
|||||||
full_reload: bool = False,
|
full_reload: bool = False,
|
||||||
force_reload: bool = False,
|
force_reload: bool = False,
|
||||||
collect: bool = False,
|
collect: bool = False,
|
||||||
|
clear_errors: bool = False,
|
||||||
_internal: Optional[list] = None,
|
_internal: Optional[list] = None,
|
||||||
):
|
):
|
||||||
"""Reload the plugin registry.
|
"""Reload the plugin registry.
|
||||||
@ -317,6 +318,7 @@ class PluginsRegistry:
|
|||||||
full_reload (bool, optional): Reload everything - including plugin mechanism. Defaults to False.
|
full_reload (bool, optional): Reload everything - including plugin mechanism. Defaults to False.
|
||||||
force_reload (bool, optional): Also reload base apps. Defaults to False.
|
force_reload (bool, optional): Also reload base apps. Defaults to False.
|
||||||
collect (bool, optional): Collect plugins before reloading. Defaults to False.
|
collect (bool, optional): Collect plugins before reloading. Defaults to False.
|
||||||
|
clear_errors (bool, optional): Clear any previous loading errors. Defaults to False.
|
||||||
_internal (list, optional): Internal apps to reload (used for testing). Defaults to None
|
_internal (list, optional): Internal apps to reload (used for testing). Defaults to None
|
||||||
"""
|
"""
|
||||||
# Do not reload when currently loading
|
# Do not reload when currently loading
|
||||||
@ -324,7 +326,15 @@ class PluginsRegistry:
|
|||||||
logger.debug('Skipping reload - plugin registry is currently loading')
|
logger.debug('Skipping reload - plugin registry is currently loading')
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.loading_lock.acquire(blocking=False):
|
if not self.loading_lock.acquire(blocking=False):
|
||||||
|
logger.exception('Could not acquire lock for reload_plugins')
|
||||||
|
return
|
||||||
|
|
||||||
|
# Reset the loading error state
|
||||||
|
if clear_errors:
|
||||||
|
self.errors = {}
|
||||||
|
|
||||||
|
try:
|
||||||
logger.info(
|
logger.info(
|
||||||
'Plugin Registry: Reloading plugins - Force: %s, Full: %s, Collect: %s',
|
'Plugin Registry: Reloading plugins - Force: %s, Full: %s, Collect: %s',
|
||||||
force_reload,
|
force_reload,
|
||||||
@ -343,10 +353,15 @@ class PluginsRegistry:
|
|||||||
self._load_plugins(full_reload=full_reload, _internal=_internal)
|
self._load_plugins(full_reload=full_reload, _internal=_internal)
|
||||||
|
|
||||||
self.update_plugin_hash()
|
self.update_plugin_hash()
|
||||||
|
|
||||||
self.loading_lock.release()
|
|
||||||
logger.info('Plugin Registry: Loaded %s plugins', len(self.plugins))
|
logger.info('Plugin Registry: Loaded %s plugins', len(self.plugins))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception('Expected error during plugin reload: %s', e)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Ensure the lock is released always
|
||||||
|
self.loading_lock.release()
|
||||||
|
|
||||||
def plugin_dirs(self):
|
def plugin_dirs(self):
|
||||||
"""Construct a list of directories from where plugins can be loaded."""
|
"""Construct a list of directories from where plugins can be loaded."""
|
||||||
# Builtin plugins are *always* loaded
|
# Builtin plugins are *always* loaded
|
||||||
|
@ -213,6 +213,7 @@ class PluginReloadSerializer(serializers.Serializer):
|
|||||||
full_reload=self.validated_data.get('full_reload', False),
|
full_reload=self.validated_data.get('full_reload', False),
|
||||||
force_reload=self.validated_data.get('force_reload', False),
|
force_reload=self.validated_data.get('force_reload', False),
|
||||||
collect=self.validated_data.get('collect_plugins', False),
|
collect=self.validated_data.get('collect_plugins', False),
|
||||||
|
clear_errors=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,11 +35,15 @@ class UsersConfig(AppConfig):
|
|||||||
rebuild_all_permissions()
|
rebuild_all_permissions()
|
||||||
except (OperationalError, ProgrammingError):
|
except (OperationalError, ProgrammingError):
|
||||||
pass
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception('Failed to rebuild permissions: %s', e)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.update_owners()
|
self.update_owners()
|
||||||
except (OperationalError, ProgrammingError):
|
except (OperationalError, ProgrammingError):
|
||||||
pass
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception('Failed to update owners: %s', e)
|
||||||
|
|
||||||
def update_owners(self):
|
def update_owners(self):
|
||||||
"""Create an 'owner' object for each user and group instance."""
|
"""Create an 'owner' object for each user and group instance."""
|
||||||
|
Reference in New Issue
Block a user