New Features
Generate command improvements:
- Annotated config generation — pg_doorman generate now produces well-documented configs with inline comments for every parameter (default behavior)
- --reference — generate a complete reference config with example values, no PostgreSQL connection needed
- --format (-f) — explicitly choose output format (yaml/toml), default changed to YAML
- --russian-comments (--ru) — generate comments in Russian for quick start
- --no-comments — plain config without inline comments (old behavior)
- Root pg_doorman.toml and pg_doorman.yaml are now auto-generated from code, ensuring they always stay in sync
Connection management:
- Configuration test mode (-t / --test-config) — validate config and exit without starting the server, useful for CI/CD
- Configuration validation before binary upgrade — SIGINT now validates the new binary's config before proceeding; cancels shutdown on failure
- server_idle_check_timeout — check idle server connections before giving to clients (default: 30s), detects dead connections from PG restarts or network issues
- tcp_user_timeout — TCP_USER_TIMEOUT for client connections (default: 60s, Linux only), prevents 15-16 minute delays on dead connections
- retain_connections_max — control max idle connections closed per retain cycle (default: 3), with oldest-first closure order
- server_lifetime jitter (±20%) — prevents mass connection expirations under load
Simplifications:
- Removed wait_rollback mechanism — was causing protocol desync with async clients
- Removed savepoint tracking — savepoints are now handled as regular PostgreSQL commands
Performance
- Removed timeout-based waiting in async protocol — response tracking by batch operations, eliminates unnecessary latency in pipeline/async workloads
Bug Fixes
- Fixed protocol desync on prepared statement cache eviction in async mode — CloseComplete and ReadyForQuery were left unread in TCP buffer during LRU eviction with Flush-based pipelines (asyncpg/SQLAlchemy)
- Fixed protocol violation on flush timeout — clients now receive proper ErrorResponse (SQLSTATE 58006) instead of TCP connection drop
- Fixed protocol desync in async mode with simple prepared statements — batch operations are now tracked regardless of prepared_statements setting