|
@@ -12,6 +12,10 @@ from supply_infra.db.base import Base
|
|
|
|
|
|
|
|
_engine: Any = None
|
|
_engine: Any = None
|
|
|
_SessionLocal: sessionmaker[Session] | None = None
|
|
_SessionLocal: sessionmaker[Session] | None = None
|
|
|
|
|
+# Process-local pool override. Used by parallel step workers so we can grow
|
|
|
|
|
+# this process's pool without mutating MYSQL_POOL_SIZE_CONTROL (which would
|
|
|
|
|
+# re-validate and explode the fleet-wide connection budget).
|
|
|
|
|
+_pool_size_override: int | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
def _set_mysql_session_china_time(
|
|
def _set_mysql_session_china_time(
|
|
@@ -26,6 +30,12 @@ def _set_mysql_session_china_time(
|
|
|
cursor.close()
|
|
cursor.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def _resolve_pool_size() -> int:
|
|
|
|
|
+ if _pool_size_override is not None:
|
|
|
|
|
+ return max(1, int(_pool_size_override))
|
|
|
|
|
+ return get_infra_settings().selected_mysql_pool_size
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def get_engine():
|
|
def get_engine():
|
|
|
"""Lazy-init SQLAlchemy engine (singleton)."""
|
|
"""Lazy-init SQLAlchemy engine (singleton)."""
|
|
|
global _engine, _SessionLocal
|
|
global _engine, _SessionLocal
|
|
@@ -33,7 +43,7 @@ def get_engine():
|
|
|
settings = get_infra_settings()
|
|
settings = get_infra_settings()
|
|
|
_engine = create_engine(
|
|
_engine = create_engine(
|
|
|
settings.mysql_url,
|
|
settings.mysql_url,
|
|
|
- pool_size=settings.selected_mysql_pool_size,
|
|
|
|
|
|
|
+ pool_size=_resolve_pool_size(),
|
|
|
max_overflow=settings.mysql_max_overflow,
|
|
max_overflow=settings.mysql_max_overflow,
|
|
|
pool_timeout=settings.mysql_pool_timeout_seconds,
|
|
pool_timeout=settings.mysql_pool_timeout_seconds,
|
|
|
pool_recycle=settings.mysql_pool_recycle_seconds,
|
|
pool_recycle=settings.mysql_pool_recycle_seconds,
|
|
@@ -64,20 +74,19 @@ def dispose_engine() -> None:
|
|
|
|
|
|
|
|
|
|
|
|
|
def ensure_mysql_pool_capacity(min_connections: int) -> None:
|
|
def ensure_mysql_pool_capacity(min_connections: int) -> None:
|
|
|
- """Grow the process-local pool before parallel DB access in the same process."""
|
|
|
|
|
|
|
+ """Grow the process-local pool before parallel DB access in the same process.
|
|
|
|
|
+
|
|
|
|
|
+ Must not mutate MYSQL_POOL_SIZE_CONTROL: that setting feeds the fleet-wide
|
|
|
|
|
+ connection budget validator. Raising it for a single step (e.g. to 5) makes
|
|
|
|
|
+ required connections jump to 60 against a 40 budget and crashes the step.
|
|
|
|
|
+ """
|
|
|
|
|
+ global _pool_size_override
|
|
|
|
|
+
|
|
|
required = max(1, int(min_connections))
|
|
required = max(1, int(min_connections))
|
|
|
- settings = get_infra_settings()
|
|
|
|
|
- if settings.selected_mysql_pool_size >= required:
|
|
|
|
|
|
|
+ if _resolve_pool_size() >= required:
|
|
|
return
|
|
return
|
|
|
|
|
|
|
|
- import os
|
|
|
|
|
-
|
|
|
|
|
- role = settings.process_role
|
|
|
|
|
- if role in {"scheduler", "worker", "reconciler", "step"}:
|
|
|
|
|
- os.environ["MYSQL_POOL_SIZE_CONTROL"] = str(required)
|
|
|
|
|
- else:
|
|
|
|
|
- os.environ["MYSQL_POOL_SIZE"] = str(required)
|
|
|
|
|
- get_infra_settings.cache_clear()
|
|
|
|
|
|
|
+ _pool_size_override = required
|
|
|
dispose_engine()
|
|
dispose_engine()
|
|
|
|
|
|
|
|
|
|
|