fix(db): pool_size default 24 to fit transfer-bot's 20 worker threads

The previous default of 8 was a regression risk: cm_transfer_credit.py
uses ThreadPoolExecutor with CM_TRANSFER_MAX_THREADS (default 20 in
prod compose), so up to 20 threads concurrently call self.db.query().
With pool_size=8, the 9th-20th threads would hit PoolError, which
gets caught by 'except Error' and silently returns []/False — making
transfers fail with no obvious cause.

Default bumped to 24 (covers the 20-thread default with 4 in reserve).
mysql.connector caps pool_size at 32; clamping with a clear log line
so a future operator who pushes CM_TRANSFER_MAX_THREADS too high gets
a readable message instead of a library traceback.

Operator note: if you raise CM_TRANSFER_MAX_THREADS, also raise
DB_POOL_SIZE to at least the same value (max 32). At 32 threads with
4 services × 32 = 128 conns total, still well under MySQL's default
max_connections=151.
This commit is contained in:
yiekheng 2026-05-03 10:56:17 +08:00
parent a42fdf54b0
commit 324c88e652

View File

@ -20,6 +20,19 @@ _pool_lock = threading.Lock()
def _build_pool() -> "pooling.MySQLConnectionPool":
# pool_size default of 24 covers transfer-bot at full tilt:
# CM_TRANSFER_MAX_THREADS defaults to 20, each thread can hold one
# connection for the duration of a transfer step. A smaller pool
# would surface as PoolError (caught silently by query/execute) and
# transfers would fail without obvious cause. mysql.connector caps
# pool_size at 32; if you bump CM_TRANSFER_MAX_THREADS, set
# DB_POOL_SIZE to at least the same value, capped at 32.
pool_size = int(os.getenv("DB_POOL_SIZE", "24"))
if pool_size > 32:
# Hard cap from mysql.connector; clamp here so the misconfigured
# value gets a clean message instead of a cryptic library error.
print(f"DB_POOL_SIZE={pool_size} exceeds mysql.connector max (32); clamping to 32")
pool_size = 32
config = {
"host": _get_required_env("DB_HOST"),
"user": _get_required_env("DB_USER"),
@ -28,7 +41,7 @@ def _build_pool() -> "pooling.MySQLConnectionPool":
"port": int(_get_required_env("DB_PORT")),
"connection_timeout": int(_get_required_env("DB_CONNECTION_TIMEOUT")),
"pool_name": "cm_pool",
"pool_size": int(os.getenv("DB_POOL_SIZE", "8")),
"pool_size": pool_size,
"pool_reset_session": True,
}
return pooling.MySQLConnectionPool(**config)