mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 02:35:14 +00:00
Plugin discovery fix
Fixed problem where plugins were trying to load before DB was ready.
This commit is contained in:
parent
5b31440018
commit
1200d7d894
2 changed files with 59 additions and 11 deletions
|
|
@ -1,4 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
import os
|
||||
import sys
|
||||
from django.db.models.signals import post_migrate
|
||||
|
||||
|
||||
class PluginsConfig(AppConfig):
|
||||
|
|
@ -6,14 +9,46 @@ class PluginsConfig(AppConfig):
|
|||
verbose_name = "Plugins"
|
||||
|
||||
def ready(self):
|
||||
# Perform plugin discovery on startup
|
||||
try:
|
||||
from .loader import PluginManager
|
||||
"""Wire up plugin discovery without hitting the DB during app init.
|
||||
|
||||
PluginManager.get().discover_plugins()
|
||||
- Skip during common management commands that don't need discovery.
|
||||
- Register post_migrate handler to sync plugin registry to DB after migrations.
|
||||
- Do an in-memory discovery (no DB) so registry is available early.
|
||||
"""
|
||||
try:
|
||||
# Allow explicit opt-out via env var
|
||||
if os.environ.get("DISPATCHARR_SKIP_PLUGIN_AUTODISCOVERY", "").lower() in ("1", "true", "yes"):
|
||||
return
|
||||
|
||||
argv = sys.argv[1:] if len(sys.argv) > 1 else []
|
||||
mgmt_cmds_to_skip = {
|
||||
# Skip immediate discovery for these commands
|
||||
"makemigrations", "collectstatic", "check", "test", "shell", "showmigrations",
|
||||
}
|
||||
if argv and argv[0] in mgmt_cmds_to_skip:
|
||||
return
|
||||
|
||||
# Run discovery with DB sync after the plugins app has been migrated
|
||||
def _post_migrate_discover(sender=None, app_config=None, **kwargs):
|
||||
try:
|
||||
if app_config and getattr(app_config, 'label', None) != 'plugins':
|
||||
return
|
||||
from .loader import PluginManager
|
||||
PluginManager.get().discover_plugins(sync_db=True)
|
||||
except Exception:
|
||||
import logging
|
||||
logging.getLogger(__name__).exception("Plugin discovery failed in post_migrate")
|
||||
|
||||
post_migrate.connect(
|
||||
_post_migrate_discover,
|
||||
dispatch_uid="apps.plugins.post_migrate_discover",
|
||||
)
|
||||
|
||||
# Perform non-DB discovery now to populate in-memory registry.
|
||||
from .loader import PluginManager
|
||||
PluginManager.get().discover_plugins(sync_db=False)
|
||||
except Exception:
|
||||
# Avoid breaking startup due to plugin errors
|
||||
import logging
|
||||
|
||||
logging.getLogger(__name__).exception("Plugin discovery failed during app ready")
|
||||
|
||||
logging.getLogger(__name__).exception("Plugin discovery wiring failed during app ready")
|
||||
|
|
|
|||
|
|
@ -45,8 +45,11 @@ class PluginManager:
|
|||
if self.plugins_dir not in sys.path:
|
||||
sys.path.append(self.plugins_dir)
|
||||
|
||||
def discover_plugins(self) -> Dict[str, LoadedPlugin]:
|
||||
logger.info(f"Discovering plugins in {self.plugins_dir}")
|
||||
def discover_plugins(self, *, sync_db: bool = True) -> Dict[str, LoadedPlugin]:
|
||||
if sync_db:
|
||||
logger.info(f"Discovering plugins in {self.plugins_dir}")
|
||||
else:
|
||||
logger.debug(f"Discovering plugins (no DB sync) in {self.plugins_dir}")
|
||||
self._registry.clear()
|
||||
|
||||
try:
|
||||
|
|
@ -66,8 +69,13 @@ class PluginManager:
|
|||
except FileNotFoundError:
|
||||
logger.warning(f"Plugins directory not found: {self.plugins_dir}")
|
||||
|
||||
# Sync DB records
|
||||
self._sync_db_with_registry()
|
||||
# Sync DB records (optional)
|
||||
if sync_db:
|
||||
try:
|
||||
self._sync_db_with_registry()
|
||||
except Exception:
|
||||
# Defer sync if database is not ready (e.g., first startup before migrate)
|
||||
logger.exception("Deferring plugin DB sync; database not ready yet")
|
||||
return self._registry
|
||||
|
||||
def _load_plugin(self, key: str, path: str):
|
||||
|
|
@ -156,7 +164,12 @@ class PluginManager:
|
|||
from .models import PluginConfig
|
||||
|
||||
plugins: List[Dict[str, Any]] = []
|
||||
configs = {c.key: c for c in PluginConfig.objects.all()}
|
||||
try:
|
||||
configs = {c.key: c for c in PluginConfig.objects.all()}
|
||||
except Exception as e:
|
||||
# Database might not be migrated yet; fall back to registry only
|
||||
logger.warning("PluginConfig table unavailable; listing registry only: %s", e)
|
||||
configs = {}
|
||||
|
||||
# First, include all discovered plugins
|
||||
for key, lp in self._registry.items():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue