module PostgREST.Unix ( runAppInSocket , installSignalHandlers ) where import qualified Network.Socket as Socket import qualified Network.Wai.Handler.Warp as Warp import qualified System.Posix.Signals as Signals import Network.Wai (Application) import System.Directory (removeFile) import System.IO.Error (isDoesNotExistError) import System.Posix.Files (setFileMode) import System.Posix.Types (FileMode) import qualified PostgREST.AppState as AppState import qualified PostgREST.Workers as Workers import Protolude -- | Run the PostgREST application with user defined socket. runAppInSocket :: Warp.Settings -> Application -> FileMode -> FilePath -> IO () runAppInSocket settings app socketFileMode socketFilePath = do sock <- createAndBindSocket putStrLn $ ("Listening on unix socket " :: Text) <> show socketFilePath Socket.listen sock Socket.maxListenQueue Warp.runSettingsSocket settings sock app Socket.close sock where createAndBindSocket = do deleteSocketFileIfExist socketFilePath sock <- Socket.socket Socket.AF_UNIX Socket.Stream Socket.defaultProtocol Socket.bind sock $ Socket.SockAddrUnix socketFilePath setFileMode socketFilePath socketFileMode return sock deleteSocketFileIfExist path = removeFile path `catch` handleDoesNotExist handleDoesNotExist e | isDoesNotExistError e = return () | otherwise = throwIO e -- | Set signal handlers, only for systems with signals installSignalHandlers :: AppState.AppState -> IO () installSignalHandlers appState = do -- Releases the connection pool whenever the program is terminated, -- see https://github.com/PostgREST/postgrest/issues/268 install Signals.sigINT $ AppState.releasePool appState install Signals.sigTERM $ AppState.releasePool appState -- The SIGUSR1 signal updates the internal 'DbStructure' by running -- 'connectionWorker' exactly as before. install Signals.sigUSR1 $ Workers.connectionWorker appState -- Re-read the config on SIGUSR2 install Signals.sigUSR2 $ Workers.reReadConfig False appState where install signal handler = void $ Signals.installHandler signal (Signals.Catch handler) Nothing