From aa8a181014c7b52e17151a60cf4bd4b1c5c0e3d1 Mon Sep 17 00:00:00 2001 From: Amin Ghadersohi Date: Wed, 13 May 2026 17:40:10 +0000 Subject: [PATCH] fix(mcp): add threading lock to registry plugin loader _ensure_plugins_loaded() used an unprotected boolean flag, making it unsafe under concurrent first-call scenarios (e.g. gunicorn multi-thread workers). Double-checked locking with threading.Lock eliminates the race. Co-Authored-By: Claude Sonnet 4.6 --- superset/mcp_service/chart/registry.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) mode change 100644 => 100755 superset/mcp_service/chart/registry.py diff --git a/superset/mcp_service/chart/registry.py b/superset/mcp_service/chart/registry.py old mode 100644 new mode 100755 index 5b8f4c9515f..005b17ce327 --- a/superset/mcp_service/chart/registry.py +++ b/superset/mcp_service/chart/registry.py @@ -37,6 +37,7 @@ Usage:: from __future__ import annotations import logging +import threading from typing import TYPE_CHECKING if TYPE_CHECKING: @@ -46,6 +47,7 @@ logger = logging.getLogger(__name__) _REGISTRY: dict[str, "ChartTypePlugin"] = {} _plugins_loaded = False +_plugins_lock = threading.Lock() def _ensure_plugins_loaded() -> None: @@ -56,9 +58,12 @@ def _ensure_plugins_loaded() -> None: directly without first importing app.py. """ global _plugins_loaded - if not _plugins_loaded: - _plugins_loaded = True - import superset.mcp_service.chart.plugins # noqa: F401 + if _plugins_loaded: + return + with _plugins_lock: + if not _plugins_loaded: + _plugins_loaded = True + import superset.mcp_service.chart.plugins # noqa: F401 def register(plugin: "ChartTypePlugin") -> None: