mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +00:00 
			
		
		
		
	Skip ready functions if not in main thread or plugins are not loaded yet
This commit is contained in:
		| @@ -14,7 +14,8 @@ from django.db.utils import IntegrityError | |||||||
| import InvenTree.conversion | import InvenTree.conversion | ||||||
| import InvenTree.tasks | import InvenTree.tasks | ||||||
| from InvenTree.config import get_setting | from InvenTree.config import get_setting | ||||||
| from InvenTree.ready import canAppAccessDatabase, isInTestMode | from InvenTree.ready import (canAppAccessDatabase, isInMainThread, | ||||||
|  |                              isInTestMode, isPluginRegistryLoaded) | ||||||
|  |  | ||||||
| logger = logging.getLogger("inventree") | logger = logging.getLogger("inventree") | ||||||
|  |  | ||||||
| @@ -34,6 +35,10 @@ class InvenTreeConfig(AppConfig): | |||||||
|         - Collecting notification methods |         - Collecting notification methods | ||||||
|         - Adding users set in the current environment |         - 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: |         if canAppAccessDatabase() or settings.TESTING_ENV: | ||||||
|             InvenTree.tasks.check_for_migrations(worker=False) |             InvenTree.tasks.check_for_migrations(worker=False) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| """Functions to check if certain parts of InvenTree are ready.""" | """Functions to check if certain parts of InvenTree are ready.""" | ||||||
|  |  | ||||||
|  | import os | ||||||
| import sys | import sys | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -13,6 +14,20 @@ def isImportingData(): | |||||||
|     return 'loaddata' in sys.argv |     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): | 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. |     """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 False | ||||||
|  |  | ||||||
|     return True |     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 | ||||||
|   | |||||||
| @@ -12,7 +12,8 @@ from django.conf import settings | |||||||
| from django.core.exceptions import AppRegistryNotReady | from django.core.exceptions import AppRegistryNotReady | ||||||
| from django.db.utils import OperationalError | from django.db.utils import OperationalError | ||||||
|  |  | ||||||
| from InvenTree.ready import canAppAccessDatabase | from InvenTree.ready import (canAppAccessDatabase, isInMainThread, | ||||||
|  |                              isPluginRegistryLoaded) | ||||||
|  |  | ||||||
| logger = logging.getLogger("inventree") | logger = logging.getLogger("inventree") | ||||||
|  |  | ||||||
| @@ -35,6 +36,10 @@ class LabelConfig(AppConfig): | |||||||
|  |  | ||||||
|     def ready(self): |     def ready(self): | ||||||
|         """This function is called whenever the label app is loaded.""" |         """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(): |         if canAppAccessDatabase(): | ||||||
|  |  | ||||||
|             try: |             try: | ||||||
|   | |||||||
| @@ -5,7 +5,8 @@ import logging | |||||||
| from django.apps import AppConfig | from django.apps import AppConfig | ||||||
| from django.db.utils import OperationalError, ProgrammingError | 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") | logger = logging.getLogger("inventree") | ||||||
|  |  | ||||||
| @@ -16,6 +17,10 @@ class PartConfig(AppConfig): | |||||||
|  |  | ||||||
|     def ready(self): |     def ready(self): | ||||||
|         """This function is called whenever the Part app is loaded.""" |         """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(): |         if canAppAccessDatabase(): | ||||||
|             self.update_trackable_status() |             self.update_trackable_status() | ||||||
|             self.reset_part_pricing_flags() |             self.reset_part_pricing_flags() | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ from django.apps import AppConfig | |||||||
|  |  | ||||||
| from maintenance_mode.core import set_maintenance_mode | from maintenance_mode.core import set_maintenance_mode | ||||||
|  |  | ||||||
| from InvenTree.ready import canAppAccessDatabase | from InvenTree.ready import canAppAccessDatabase, isInMainThread | ||||||
| from plugin import registry | from plugin import registry | ||||||
|  |  | ||||||
| logger = logging.getLogger('inventree') | logger = logging.getLogger('inventree') | ||||||
| @@ -23,6 +23,10 @@ class PluginAppConfig(AppConfig): | |||||||
|  |  | ||||||
|     def ready(self): |     def ready(self): | ||||||
|         """The ready method is extended to initialize plugins.""" |         """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): |         if not canAppAccessDatabase(allow_test=True, allow_plugins=True): | ||||||
|             logger.info("Skipping plugin loading sequence")  # pragma: no cover |             logger.info("Skipping plugin loading sequence")  # pragma: no cover | ||||||
|         else: |         else: | ||||||
|   | |||||||
| @@ -18,7 +18,12 @@ class ReportConfig(AppConfig): | |||||||
|     def ready(self): |     def ready(self): | ||||||
|         """This function is called whenever the report app is loaded.""" |         """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) |         # Configure logging for PDF generation (disable "info" messages) | ||||||
|         logging.getLogger('fontTools').setLevel(logging.WARNING) |         logging.getLogger('fontTools').setLevel(logging.WARNING) | ||||||
|   | |||||||
| @@ -5,7 +5,8 @@ import logging | |||||||
| from django.apps import AppConfig | from django.apps import AppConfig | ||||||
| from django.db.utils import OperationalError, ProgrammingError | from django.db.utils import OperationalError, ProgrammingError | ||||||
|  |  | ||||||
| from InvenTree.ready import canAppAccessDatabase | from InvenTree.ready import (canAppAccessDatabase, isInMainThread, | ||||||
|  |                              isPluginRegistryLoaded) | ||||||
|  |  | ||||||
| logger = logging.getLogger('inventree') | logger = logging.getLogger('inventree') | ||||||
|  |  | ||||||
| @@ -17,6 +18,11 @@ class UsersConfig(AppConfig): | |||||||
|  |  | ||||||
|     def ready(self): |     def ready(self): | ||||||
|         """Called when the 'users' app is loaded at runtime""" |         """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): |         if canAppAccessDatabase(allow_test=True): | ||||||
|  |  | ||||||
|             try: |             try: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user