2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-18 21:15:41 +00:00

Skip ready functions if not in main thread or plugins are not loaded yet

This commit is contained in:
wolflu05
2023-06-08 21:06:14 +00:00
parent f1031efa93
commit e7f546b8b0
7 changed files with 69 additions and 6 deletions

View File

@ -14,7 +14,8 @@ from django.db.utils import IntegrityError
import InvenTree.conversion
import InvenTree.tasks
from InvenTree.config import get_setting
from InvenTree.ready import canAppAccessDatabase, isInTestMode
from InvenTree.ready import (canAppAccessDatabase, isInMainThread,
isInTestMode, isPluginRegistryLoaded)
logger = logging.getLogger("inventree")
@ -34,6 +35,10 @@ class InvenTreeConfig(AppConfig):
- Collecting notification methods
- Adding users set in the current environment
"""
# skip loading if plugins are not loaded or we run in a background thread
if not isPluginRegistryLoaded() or not isInMainThread():
return
if canAppAccessDatabase() or settings.TESTING_ENV:
InvenTree.tasks.check_for_migrations(worker=False)

View File

@ -1,5 +1,6 @@
"""Functions to check if certain parts of InvenTree are ready."""
import os
import sys
@ -13,6 +14,20 @@ def isImportingData():
return 'loaddata' in sys.argv
def isInMainThread():
"""Django starts two processes, one for the actual dev server and the other to reload the application.
- The RUN_MAIN env is set in that case. However if --noreload is applied, this variable
is not set because there are no different threads.
- If this app is run in gunicorn there are several threads having "equal rights" so there is no real
main thread so we skip this check
"""
if '--noreload' in sys.argv or "gunicorn" in os.environ.get("SERVER_SOFTWARE", ""):
return True
return os.environ.get('RUN_MAIN', None) == 'true'
def canAppAccessDatabase(allow_test: bool = False, allow_plugins: bool = False, allow_shell: bool = False):
"""Returns True if the apps.py file can access database records.
@ -60,3 +75,21 @@ def canAppAccessDatabase(allow_test: bool = False, allow_plugins: bool = False,
return False
return True
def isPluginRegistryLoaded():
"""The plugin registry reloads all apps onetime after starting so that the discovered AppConfigs are added to Django.
This triggers the ready function of AppConfig to execute twice. Add this check to prevent from running two times.
Returns: 'False' if the apps have not been reloaded already to prevent running the ready function twice
"""
from django.conf import settings
# If plugins are not enabled, there won't be a second load
if not settings.PLUGINS_ENABLED:
return True
from plugin import registry
return not registry.is_loading

View File

@ -12,7 +12,8 @@ from django.conf import settings
from django.core.exceptions import AppRegistryNotReady
from django.db.utils import OperationalError
from InvenTree.ready import canAppAccessDatabase
from InvenTree.ready import (canAppAccessDatabase, isInMainThread,
isPluginRegistryLoaded)
logger = logging.getLogger("inventree")
@ -35,6 +36,10 @@ class LabelConfig(AppConfig):
def ready(self):
"""This function is called whenever the label app is loaded."""
# skip loading if plugins are not loaded or we run in a background thread
if not isPluginRegistryLoaded() or not isInMainThread():
return
if canAppAccessDatabase():
try:

View File

@ -5,7 +5,8 @@ import logging
from django.apps import AppConfig
from django.db.utils import OperationalError, ProgrammingError
from InvenTree.ready import canAppAccessDatabase, isImportingData
from InvenTree.ready import (canAppAccessDatabase, isImportingData,
isInMainThread, isPluginRegistryLoaded)
logger = logging.getLogger("inventree")
@ -16,6 +17,10 @@ class PartConfig(AppConfig):
def ready(self):
"""This function is called whenever the Part app is loaded."""
# skip loading if plugins are not loaded or we run in a background thread
if not isPluginRegistryLoaded() or not isInMainThread():
return
if canAppAccessDatabase():
self.update_trackable_status()
self.reset_part_pricing_flags()

View File

@ -10,7 +10,7 @@ from django.apps import AppConfig
from maintenance_mode.core import set_maintenance_mode
from InvenTree.ready import canAppAccessDatabase
from InvenTree.ready import canAppAccessDatabase, isInMainThread
from plugin import registry
logger = logging.getLogger('inventree')
@ -23,6 +23,10 @@ class PluginAppConfig(AppConfig):
def ready(self):
"""The ready method is extended to initialize plugins."""
# skip loading if we run in a background thread
if not isInMainThread():
return
if not canAppAccessDatabase(allow_test=True, allow_plugins=True):
logger.info("Skipping plugin loading sequence") # pragma: no cover
else:

View File

@ -18,7 +18,12 @@ class ReportConfig(AppConfig):
def ready(self):
"""This function is called whenever the report app is loaded."""
from InvenTree.ready import canAppAccessDatabase
from InvenTree.ready import (canAppAccessDatabase, isInMainThread,
isPluginRegistryLoaded)
# skip loading if plugins are not loaded or we run in a background thread
if not isPluginRegistryLoaded() or not isInMainThread():
return
# Configure logging for PDF generation (disable "info" messages)
logging.getLogger('fontTools').setLevel(logging.WARNING)

View File

@ -5,7 +5,8 @@ import logging
from django.apps import AppConfig
from django.db.utils import OperationalError, ProgrammingError
from InvenTree.ready import canAppAccessDatabase
from InvenTree.ready import (canAppAccessDatabase, isInMainThread,
isPluginRegistryLoaded)
logger = logging.getLogger('inventree')
@ -17,6 +18,11 @@ class UsersConfig(AppConfig):
def ready(self):
"""Called when the 'users' app is loaded at runtime"""
# skip loading if plugins are not loaded or we run in a background thread
if not isPluginRegistryLoaded() or not isInMainThread():
return
if canAppAccessDatabase(allow_test=True):
try: