fix(rds): connect_timeout on RdsServiceGateway so connects fail fast - #153
Conversation
RdsServiceGateway built its ThreadedConnectionPool (and the reconnect() pool rebuild / single-connection reconnect) with a bare DSN and no connect_timeout, so an unreachable or saturated database caused connection construction to block indefinitely — a consumer's startup could hang forever with no recovery path. This turned a transient prod DB CPU saturation into a multi-minute downstream outage (AiAxis 502 boot loop; Datadog BUG-96). Add a connect_timeout parameter (default 10s, floored to the libpq minimum of 2s) threaded through every connection site: the pool constructor, the reconnect() pool rebuild, and the single-connection reconnect. Connections now fail fast instead of hanging, letting consumers surface the error and recover.
PR Review — APPROVEAdds Nits
ContextDiff: 2 files, +55/−5 · Prior reviews: none · Related: Datadog BUG-96; consumer bump PRs forthcoming in AiAxis and ai-pipeline per PR body — Claude |
Wrench-Review-Bot
left a comment
There was a problem hiding this comment.
PR Review — APPROVE
Adds connect_timeout (default 10 s, floored to libpq minimum 2 s) to RdsServiceGateway and threads it through the three psycopg2 connection sites the class owns: pool construction, pool rebuild in reconnect(), and single-connection rebuild in reconnect(). Targeted, backward-compatible fix for BUG-96.
Nits
- Nit:
WrenchCL/Connect/AwsClientHub.py:179— The initial single-connection path (non-multithreaded__init__) goes throughAwsClientHub._rds_handle_configuration→psycopg2.connect(host=..., port=..., ...)with noconnect_timeout. A saturated DB would still hang the first connect in non-multithreaded mode. This is pre-existing ambient debt inAwsClientHub, not introduced here; the pool / reconnect paths (the BUG-96 scenario) are correctly fixed. Worth a follow-up PR onAwsClientHub._rds_handle_configuration. - Nit:
WrenchCL/Connect/RdsServiceGateway.py:39— type annotation isintbut the assignmentmax(2, int(connect_timeout))silently accepts floats.Union[int, float]would be more accurate, or add a# type: ignoreif the narrower hint is intentional.
Context
Diff: 2 files, +55/−5 · Prior reviews: none · Related: Datadog BUG-96; consumer bump PRs forthcoming in AiAxis and ai-pipeline per PR body
— Claude
|
✅ PR Review complete — APPROVED. Full review ↗ |
Fixes
RdsServiceGatewaybuilt itsThreadedConnectionPool(and thereconnect()pool rebuild and single-connection reconnect) with a bare DSN and noconnect_timeout, so libpq waited indefinitely for each connect. A consumer whose worker builds the pool at startup could hang forever with no recovery. This is the library-level root cause behind Datadog BUG-96: a transient prod DB CPU saturation left AiAxis hung on pool construction and boot-looping (HTTP 502) for ~40 minutes.connect_timeoutparameter (default 10s, floored to the libpq minimum of 2s) threaded through all three connection sites. Connects now fail fast so consumers can surface the error and self-heal.Tests
connect_timeout, and added coverage for default / custom / floored values on the pool constructor. Fulltests/suite green (159 passed), ruff clean.Impact
Backward compatible — new optional parameter with a safe default; every existing consumer immediately gains fail-fast connects with no code change. Consumers that want a tighter bound (e.g. AiAxis) can pass a smaller value.
References