Skip to content

Commit aa8ec5a

Browse files
committed
fix: default DB_POOL_TIMEOUT to 5 s
1 parent b6b8e68 commit aa8ec5a

3 files changed

Lines changed: 6 additions & 2 deletions

File tree

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Endpoints inject a use case with `FromDI(UseCase)` from `modern_di_fastapi`, cal
6060

6161
### Pool and server sizing
6262

63-
`DB_POOL_SIZE` (positive) and `DB_MAX_OVERFLOW` (non-negative) size the pool, and a request that finds it empty waits for a connection. Granian's `backpressure` is left at its default: it limits open connections per worker, idle keep-alive ones included, so setting it to the pool size makes new connections wait while the app is idle. `APP_WORKERS` sets the Granian worker count, and each worker has its own pool. `DB_POOL_TIMEOUT` (default 30 s) bounds the wait for a connection, and a timeout returns 503 through `exceptions.database_unavailable_handler`. advanced-alchemy wraps the timeout in a `RepositoryError`, so the handler is also registered for `RepositoryError` and re-raises anything not caused by a pool timeout. `DB_POOL_RECYCLE` defaults to SQLAlchemy's `-1` (never). Set it below the idle timeout of any proxy or load balancer in front of Postgres, so a connection it dropped is not handed out and retried after a 1-2 s backoff.
63+
`DB_POOL_SIZE` (positive) and `DB_MAX_OVERFLOW` (non-negative) size the pool, and a request that finds it empty waits for a connection. Granian's `backpressure` is left at its default: it limits open connections per worker, idle keep-alive ones included, so setting it to the pool size makes new connections wait while the app is idle. `APP_WORKERS` sets the Granian worker count, and each worker has its own pool. `DB_POOL_TIMEOUT` (default 5 s) bounds the wait for a connection, and a timeout returns 503 through `exceptions.database_unavailable_handler`. advanced-alchemy wraps the timeout in a `RepositoryError`, so the handler is also registered for `RepositoryError` and re-raises anything not caused by a pool timeout. `DB_POOL_RECYCLE` defaults to SQLAlchemy's `-1` (never). Set it below the idle timeout of any proxy or load balancer in front of Postgres, so a connection it dropped is not handed out and retried after a 1-2 s backoff.
6464

6565
### Use cases and lost connections
6666

‎app/settings.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class Settings(pydantic_settings.BaseSettings):
1919
db_pool_size: pydantic.PositiveInt = 5
2020
db_max_overflow: pydantic.NonNegativeInt = 0
2121
db_pool_pre_ping: bool = False
22-
db_pool_timeout: float = 30
22+
db_pool_timeout: float = 5
2323
db_pool_recycle: int = -1
2424

2525
app_host: str = "0.0.0.0" # noqa: S104

‎tests/test_settings.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ def test_pool_pre_ping_is_off_by_default() -> None:
2020
assert Settings().db_pool_pre_ping is False
2121

2222

23+
def test_pool_timeout_defaults_to_five_seconds() -> None:
24+
assert Settings().db_pool_timeout == 5 # noqa: PLR2004
25+
26+
2327
def test_log_level_is_case_insensitive_and_reaches_app_logging() -> None:
2428
custom = Settings(log_level="WARNING")
2529

0 commit comments

Comments
 (0)