refactor: make sure proper sockets cleanup is performed in App.run
Right now code in App.run does not properly use bracket/finally to close sockets and clean-up mainSocketRef. This is not a big problem at the moment because the application is going to exit enyway but introducting proper resource handling will make future refactorings safer.
This commit is contained in:
committed by
Steve Chavez
parent
56df1dc532
commit
c5c9dc33c9
+26
-22
@@ -24,7 +24,6 @@ import GHC.IO.Exception (IOErrorType (..))
|
||||
import System.IO.Error (ioeGetErrorType)
|
||||
|
||||
import Control.Monad.Except (liftEither)
|
||||
import Control.Monad.Extra (whenJust)
|
||||
import Data.Either.Combinators (mapLeft, whenLeft)
|
||||
import Data.IORef (atomicWriteIORef, newIORef,
|
||||
readIORef)
|
||||
@@ -83,39 +82,44 @@ run appState = do
|
||||
conf <- AppState.getConfig appState
|
||||
|
||||
mainSocketRef <- newIORef Nothing
|
||||
adminSocket <- initAdminServerSocket conf
|
||||
let setMainSocketRef = atomicWriteIORef mainSocketRef . Just
|
||||
clearMainSocketRef = atomicWriteIORef mainSocketRef Nothing
|
||||
|
||||
let closeSockets = do
|
||||
whenJust adminSocket NS.close
|
||||
readIORef mainSocketRef >>= foldMap NS.close
|
||||
Unix.installSignalHandlers observer closeSockets (AppState.schemaCacheLoader appState) (AppState.readInDbConfig False appState)
|
||||
bracket (initAdminServerSocket conf) ensureSocketClosed $ \adminSocket -> do
|
||||
|
||||
Admin.runAdmin appState adminSocket (checkMainAppLive (readIORef mainSocketRef)) (serverSettings conf)
|
||||
let closeSockets = do
|
||||
ensureSocketClosed adminSocket
|
||||
ensureSocketClosed =<< readIORef mainSocketRef
|
||||
Unix.installSignalHandlers observer closeSockets (AppState.schemaCacheLoader appState) (AppState.readInDbConfig False appState)
|
||||
|
||||
Listener.runListener appState
|
||||
Admin.runAdmin appState adminSocket (checkMainAppLive (readIORef mainSocketRef)) (serverSettings conf)
|
||||
|
||||
-- Kick off and wait for the initial SchemaCache load before creating the
|
||||
-- main API socket.
|
||||
AppState.schemaCacheLoader appState
|
||||
AppState.waitForSchemaCacheInit appState
|
||||
Listener.runListener appState
|
||||
|
||||
mainSocket <- initServerSocket conf
|
||||
atomicWriteIORef mainSocketRef $ Just mainSocket
|
||||
-- Kick off and wait for the initial SchemaCache load before creating the
|
||||
-- main API socket.
|
||||
AppState.schemaCacheLoader appState
|
||||
AppState.waitForSchemaCacheInit appState
|
||||
|
||||
let app = postgrest appState (AppState.schemaCacheLoader appState)
|
||||
bracket (initServerSocket conf) NS.close $ \mainSocket -> do
|
||||
|
||||
address <- resolveSocketToAddress mainSocket
|
||||
let app = postgrest appState (AppState.schemaCacheLoader appState)
|
||||
|
||||
let
|
||||
appServerSettings = serverSettings conf
|
||||
& setPort (configServerPort conf)
|
||||
& setOnException onWarpException
|
||||
& setBeforeMainLoop (observer $ AppServerAddressObs address)
|
||||
address <- resolveSocketToAddress mainSocket
|
||||
|
||||
Warp.runSettingsSocket appServerSettings mainSocket app
|
||||
let
|
||||
appServerSettings = serverSettings conf
|
||||
& setPort (configServerPort conf)
|
||||
& setOnException onWarpException
|
||||
& setBeforeMainLoop (setMainSocketRef mainSocket *> observer (AppServerAddressObs address))
|
||||
|
||||
Warp.runSettingsSocket appServerSettings mainSocket app
|
||||
`finally` clearMainSocketRef
|
||||
where
|
||||
observer = AppState.getObserver appState
|
||||
|
||||
ensureSocketClosed = foldMap NS.close
|
||||
|
||||
onWarpException :: Maybe Wai.Request -> SomeException -> IO ()
|
||||
onWarpException _ ex =
|
||||
when (shouldDisplayException ex) $
|
||||
|
||||
Reference in New Issue
Block a user