You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,10 @@
6
6
***`::cast` injection** — cast targets in `select` are validated at parse time and rejected with 400 otherwise; a cast can't be a bind parameter, so it was interpolated verbatim and could alter the SELECT (reachable by any role that can read).
7
7
***DDL quoting** — quote the remaining `CREATE`/`ALTER DATABASE` identifiers, and whitelist grant/revoke verbs and object types instead of interpolating them.
8
8
9
+
### Added
10
+
* Shutdown now waits for in-flight requests to complete; the wait was previously hardcoded to 1 second, so every restart killed any request slower than that. The new `GracefulShutdownTimeout` config key (seconds, default 0 = wait until done) bounds the wait for deployments that want a hard cap below their supervisor's stop grace period. A second signal during the wait forces an immediate exit, and `Shutdown()` is now idempotent.
11
+
*`/ready` now reports `503 {"status":"draining"}` as soon as a graceful shutdown begins, while `/live` keeps answering 200 until the process exits — the standard probe contract for zero-downtime rolling deploys. The new `DrainDelay` config key (seconds, default 0 = disabled) keeps the listener serving for that long after readiness flips, giving load balancers time to deregister the instance before it stops accepting connections. The delay applies to SIGTERM only; an interactive Ctrl-C (SIGINT) shuts down immediately, and a second signal during the window skips it.
12
+
9
13
### Fixed
10
14
* Schema cache held in an atomic pointer (was a data race on reload).
11
15
* Serializers return an error on a malformed wire buffer or a type/dimension mismatch instead of panicking or silently misparsing.
@@ -14,6 +18,9 @@
14
18
* Boolean-filter nesting capped at 100 levels (stack-overflow DoS).
15
19
* Invalid grant input returns 400 instead of 500.
16
20
* Session watcher no longer deadlocks when paused.
21
+
***SIGTERM** — the server now shuts down gracefully on SIGTERM (the default stop signal of Docker, Kubernetes and systemd), not only on SIGINT/Ctrl-C. A raw SIGTERM previously terminated the process immediately, cutting in-flight requests and resetting database connections.
22
+
***Exit status** — a graceful shutdown now exits with status 0; it previously exited 1, which supervisors interpret as a crash.
23
+
***Database connections on shutdown** — connection pools and the notification listener's dedicated connection are now closed after the HTTP server drains, so Postgres sees clean disconnects instead of connection resets on every stop. `NotificationListener.Stop()` now interrupts a pending `WaitForNotification` and waits for the listener goroutine to exit before returning.
Copy file name to clipboardExpand all lines: README.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -772,6 +772,8 @@ The configuration file *config.jsonc* (JSON with Comments) is created automatica
772
772
| Plugins | Ordered list of plugins |[]|
773
773
| ReadTimeout | The maximum duration for reading the entire request, including the body (seconds) | 60 |
774
774
| WriteTimeout | The maximum duration before timing out writes of the response (seconds) | 60 |
775
+
| GracefulShutdownTimeout | The maximum duration to wait for in-flight requests to complete on shutdown (seconds, 0 to wait until done) | 0 |
776
+
| DrainDelay | Seconds to keep serving after /ready starts reporting 503 on a SIGTERM shutdown, so load balancers can deregister the instance; SIGINT skips the delay (0 to disable) | 0 |
775
777
| RequestMaxBytes | Max bytes allowed in requests, to limit the size of incoming request bodies (0 for unlimited) | 1048576 (1MB) |
776
778
| Database.URL | Database URL as postgresql://user:pwd@host:port/database | "" |
777
779
| Database.MinPoolConnections | Miminum connections per pool | 10 |
Plugins []string`comment:"Ordered list of plugins (default: [])"`
46
+
ReadTimeoutint64`comment:"The maximum duration (seconds) for reading the entire request, including the body (default: 60)"`
47
+
WriteTimeoutint64`comment:"The maximum duration before timing out writes of the response (default: 60)"`
48
+
GracefulShutdownTimeoutint64`comment:"The maximum duration (seconds) to wait for in-flight requests to complete on shutdown (default: 0, wait until done)"`
49
+
DrainDelayint64`comment:"Seconds to keep serving after /ready starts reporting 503 on a SIGTERM shutdown, so load balancers can deregister the instance; SIGINT skips the delay (default: 0, disabled)"`
50
+
TokenExpiryint64`comment:"JWT token expiry in seconds (default: 86400 = 24h, 0 for no expiry)"`
51
+
VerboseErrorsbool`comment:"Return full database error details (hint, detail) to clients (default: true)"`
52
+
RequestMaxBytesint64`comment:"Max bytes allowed in requests, to limit the size of incoming request bodies (default: 1M, 0 for unlimited)"`
0 commit comments