connection_budget(기본 40)을 두고, 기동 시 process_count 에 맞춰 pool_size/max_overflow 를 역산: (pool+overflow)×2엔진×process_count ≤ budget. 워커를 늘려도 config 가 스스로 예산을 지켜 커넥션 고갈→요청 실패를 예방. - config_models: MainDBConfig.connection_budget 추가 - server_configs: _autosize_pool(process_count 확정 후 산정) + _apply_pool_env_override (우선순위 = 명시 DB_POOL_SIZE > 자동 산정 > toml pool) - web_main: 기동 로그에 실효 풀/총커넥션/예산 출력 - env: DB_CONNECTION_BUDGET override, docker-compose 에 knob 노출 - tests: test_pool_autosize 10케이스(예산 준수·분할비·비활성·infeasible 바닥) - docs: operations 2-1 멀티코어/풀 섹션 + loadtest README 자동산정 표 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
"""커넥션 풀 자동 산정(_autosize_pool) — process_count 기준으로 예산을 넘지 않아야 한다."""
|
||
|
||
import pytest
|
||
|
||
from config.config_models import MainDBConfig
|
||
from config.server_configs import _autosize_pool
|
||
|
||
|
||
def _conns(cfg: MainDBConfig, pc: int) -> int:
|
||
# 실제 동시 커넥션 = (pool + overflow) × 2엔진(R/W) × process_count
|
||
return (cfg.pool_size + cfg.max_overflow) * 2 * pc
|
||
|
||
|
||
@pytest.mark.parametrize("pc", [1, 2, 4, 8, 16])
|
||
def test_autosize_within_budget(pc):
|
||
cfg = MainDBConfig(connection_budget=40)
|
||
_autosize_pool(cfg, pc)
|
||
assert _conns(cfg, pc) <= 40
|
||
assert cfg.pool_size >= 1
|
||
assert cfg.max_overflow >= 0
|
||
|
||
|
||
def test_autosize_uses_budget_efficiently():
|
||
# 예산을 지나치게 낭비하지 않아야(넉넉한 예산일 때 절반 이상 활용)
|
||
cfg = MainDBConfig(connection_budget=96)
|
||
_autosize_pool(cfg, 4)
|
||
assert _conns(cfg, 4) <= 96
|
||
assert _conns(cfg, 4) >= 96 // 2
|
||
|
||
|
||
def test_autosize_split_ratio():
|
||
# pool(정상) 이 overflow(버스트)보다 크거나 같게 분할
|
||
cfg = MainDBConfig(connection_budget=96)
|
||
_autosize_pool(cfg, 1)
|
||
assert cfg.pool_size >= cfg.max_overflow
|
||
|
||
|
||
def test_autosize_disabled_when_budget_zero():
|
||
# budget<=0 이면 자동 산정 끔 → toml/기본 pool 값 유지, None 반환
|
||
cfg = MainDBConfig(connection_budget=0, pool_size=10, max_overflow=20)
|
||
assert _autosize_pool(cfg, 4) is None
|
||
assert (cfg.pool_size, cfg.max_overflow) == (10, 20)
|
||
|
||
|
||
def test_autosize_returns_computed_pair():
|
||
cfg = MainDBConfig(connection_budget=40)
|
||
result = _autosize_pool(cfg, 2)
|
||
assert result == (cfg.pool_size, cfg.max_overflow)
|
||
|
||
|
||
def test_autosize_infeasible_process_count_floors_at_one():
|
||
# process_count×2 > budget 이면 예산 준수가 물리적으로 불가능(워커당 최소 1커넥션 필요).
|
||
# 이때는 pool_size=1/overflow=0(엔진당 1커넥션)까지 줄이는 게 한계 — 0 풀은 만들지 않는다.
|
||
cfg = MainDBConfig(connection_budget=40)
|
||
_autosize_pool(cfg, 64)
|
||
assert cfg.pool_size == 1
|
||
assert cfg.max_overflow == 0
|