Skip to content

Commit bcf3e19

Browse files
committed
fix: shutdown should wait for in flight requests
3 parents bee2ea6 + a4aa58b + 938d0d1 commit bcf3e19

5 files changed

Lines changed: 62 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ All notable changes to this project will be documented in this file. From versio
1919
- Log error when `db-schemas` config contains schema `pg_catalog` or `information_schema` by @taimoorzaeem in #4359
2020
+ Now fails at startup. Prior to this, it failed with `PGRST205` on requests related to these schemas.
2121

22+
### Fixed
23+
24+
- Shutdown should wait for in flight requests by @mkleczek in #4702
25+
2226
## [14.6] - 2026-03-06
2327

2428
### Fixed

nix/overlays/haskell-packages.nix

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,53 @@ let
7878
hasql-pool = lib.dontCheck prev.hasql-pool_1_0_1;
7979
hasql-transaction = lib.dontCheck prev.hasql-transaction_1_1_0_1;
8080
postgresql-binary = lib.dontCheck (lib.doJailbreak prev.postgresql-binary_0_13_1_3);
81+
82+
http2 =
83+
prev.callHackageDirect
84+
{
85+
pkg = "http2";
86+
ver = "5.4.0";
87+
sha256 = "sha256-PeEWVd61bQ8G7LvfLeXklzXqNJFaAjE2ecRMWJZESPE=";
88+
}
89+
{ };
90+
91+
http-semantics =
92+
prev.callHackageDirect
93+
{
94+
pkg = "http-semantics";
95+
ver = "0.4.0";
96+
sha256 = "sha256-rh0z51EKvsu5rQd5n2z3fSRjjEObouNZSBPO9NFYOF0=";
97+
}
98+
{ };
99+
100+
network-run =
101+
prev.callHackageDirect
102+
{
103+
pkg = "network-run";
104+
ver = "0.5.0";
105+
sha256 = "sha256-vbXh+CzxDsGApjqHxCYf/ijpZtUCApFbkcF5gyN0THU=";
106+
}
107+
{ };
108+
109+
time-manager =
110+
prev.callHackageDirect
111+
{
112+
pkg = "time-manager";
113+
ver = "0.2.4";
114+
sha256 = "sha256-sAt/331YLQ2IU3z90aKYSq1nxoazv87irsuJp7ZG3pw=";
115+
}
116+
{ };
117+
118+
warp =
119+
lib.dontCheck (prev.callCabal2nixWithOptions "warp"
120+
(super.fetchFromGitHub {
121+
owner = "mkleczek";
122+
repo = "wai";
123+
rev = "e9c9e784dee1b54461b94089175a969eb647d262";
124+
#sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
125+
sha256 = "sha256-q8vgvsNeKM/fHp3H6+W/tR4HicioqeaU9Eo3rb13bLo=";
126+
}) "--subpath=warp"
127+
{ });
81128
};
82129
in
83130
{

src/PostgREST/App.hs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import GHC.IO.Exception (IOErrorType (..))
2222
import System.IO.Error (ioeGetErrorType)
2323

2424
import Control.Monad.Except (liftEither)
25+
import Control.Monad.Extra (whenJust)
2526
import Data.Either.Combinators (mapLeft, whenLeft)
2627
import Data.Maybe (fromJust)
2728
import Data.String (IsString (..))
@@ -78,8 +79,10 @@ run appState = do
7879

7980
AppState.schemaCacheLoader appState -- Loads the initial SchemaCache
8081
(mainSocket, adminSocket) <- initSockets conf
81-
82-
Unix.installSignalHandlers (AppState.getMainThreadId appState) (AppState.schemaCacheLoader appState) (AppState.readInDbConfig False appState)
82+
let closeSockets = do
83+
whenJust adminSocket NS.close
84+
NS.close mainSocket
85+
Unix.installSignalHandlers closeSockets (AppState.schemaCacheLoader appState) (AppState.readInDbConfig False appState)
8386

8487
Listener.runListener appState
8588

@@ -91,6 +94,10 @@ run appState = do
9194
address <- resolveSocketToAddress mainSocket
9295
observer $ AppServerAddressObs address
9396

97+
-- Hardcoding maximum graceful shutdown timeout (arbitrary set to 5 seconds)
98+
-- This is unfortunate but necessary becase graceful shutdowns don't work with HTTP keep-alive
99+
-- causing Warp to handle requests on already opened connections even if the listen socket is closed
100+
-- See: https://github.com/yesodweb/wai/issues/853
94101
Warp.runSettingsSocket (serverSettings conf & setOnException onWarpException) mainSocket app
95102
where
96103
observer = AppState.getObserver appState

src/PostgREST/Unix.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ import System.Directory (removeFile)
1818
import System.IO.Error (isDoesNotExistError)
1919

2020
-- | Set signal handlers, only for systems with signals
21-
installSignalHandlers :: ThreadId -> IO () -> IO () -> IO ()
21+
installSignalHandlers :: IO () -> IO () -> IO () -> IO ()
2222
#ifndef mingw32_HOST_OS
23-
installSignalHandlers tid usr1 usr2 = do
24-
let interrupt = throwTo tid UserInterrupt
23+
installSignalHandlers interrupt usr1 usr2 = do
2524
install Signals.sigINT interrupt
2625
install Signals.sigTERM interrupt
2726
install Signals.sigUSR1 usr1

test/io/test_io.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ def sleep():
105105
t.join()
106106

107107

108-
@pytest.mark.xfail(reason="Graceful shutdown is currently failing", strict=True)
109108
def test_graceful_shutdown_waits_for_in_flight_request(defaultenv):
110109
"SIGTERM should allow in-flight requests to finish before exiting"
111110

0 commit comments

Comments
 (0)