@@ -22,6 +22,7 @@ import GHC.IO.Exception (IOErrorType (..))
2222import System.IO.Error (ioeGetErrorType )
2323
2424import Control.Monad.Except (liftEither )
25+ import Control.Monad.Extra (whenJust )
2526import Data.Either.Combinators (mapLeft , whenLeft )
2627import Data.Maybe (fromJust )
2728import Data.String (IsString (.. ))
@@ -79,8 +80,10 @@ run appState = do
7980
8081 AppState. schemaCacheLoader appState -- Loads the initial SchemaCache
8182 (mainSocket, adminSocket) <- initSockets conf
82-
83- Unix. installSignalHandlers observer (AppState. getMainThreadId appState) (AppState. schemaCacheLoader appState) (AppState. readInDbConfig False appState)
83+ let closeSockets = do
84+ whenJust adminSocket NS. close
85+ NS. close mainSocket
86+ Unix. installSignalHandlers observer closeSockets (AppState. schemaCacheLoader appState) (AppState. readInDbConfig False appState)
8487
8588 Listener. runListener appState
8689
@@ -92,6 +95,10 @@ run appState = do
9295 address <- resolveSocketToAddress mainSocket
9396 observer $ AppServerAddressObs address
9497
98+ -- Hardcoding maximum graceful shutdown timeout (arbitrary set to 5 seconds)
99+ -- This is unfortunate but necessary becase graceful shutdowns don't work with HTTP keep-alive
100+ -- causing Warp to handle requests on already opened connections even if the listen socket is closed
101+ -- See: https://github.com/yesodweb/wai/issues/853
95102 Warp. runSettingsSocket (serverSettings conf & setOnException onWarpException) mainSocket app
96103 where
97104 observer = AppState. getObserver appState
0 commit comments