Reload schema definition on SIGHUP (#570)
This commit is contained in:
@@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Reload database schema on SIGHUP - @begriffs
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Prevent role from being changed twice - @begriffs
|
- Prevent role from being changed twice - @begriffs
|
||||||
|
|||||||
+7
-7
@@ -328,14 +328,14 @@ OPTIONS /my_view
|
|||||||
This will include the row names, their types, primary key
|
This will include the row names, their types, primary key
|
||||||
information, and foreign keys for the given table or view.
|
information, and foreign keys for the given table or view.
|
||||||
|
|
||||||
<div class="admonition danger">
|
<div class="admonition warning">
|
||||||
<p class="admonition-title">Deprecation Warning</p>
|
<p class="admonition-title">Schema Changes</p>
|
||||||
|
|
||||||
<p>Although we currently use the OPTIONS verb for this, some
|
<p>Note that when the schema of your database changes PostgREST will not reflect
|
||||||
people <a
|
the change. You have to either restart PostgREST or send its running process
|
||||||
href="https://www.mnot.net/blog/2012/10/29/NO_OPTIONS">argue</a> that
|
a HUP signal:
|
||||||
this is inappropriate. We are considering a <code>describedby</code>
|
|
||||||
header link instead.</p>
|
<pre><code>killall -HUP postgrest</code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### CORS
|
### CORS
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ executable postgrest
|
|||||||
, string-conversions
|
, string-conversions
|
||||||
, text
|
, text
|
||||||
, time
|
, time
|
||||||
|
, transformers
|
||||||
, unordered-containers
|
, unordered-containers
|
||||||
, vector
|
, vector
|
||||||
, wai >= 3.0.1
|
, wai >= 3.0.1
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ module PostgREST.App (
|
|||||||
|
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Data.Bifunctor (first)
|
import Data.Bifunctor (first)
|
||||||
|
import Data.IORef (IORef, readIORef)
|
||||||
import Data.List (find, delete)
|
import Data.List (find, delete)
|
||||||
import Data.Maybe (isJust, fromMaybe, fromJust, mapMaybe)
|
import Data.Maybe (isJust, fromMaybe, fromJust, mapMaybe)
|
||||||
import Data.Ranged.Ranges (emptyRange)
|
import Data.Ranged.Ranges (emptyRange)
|
||||||
@@ -59,13 +60,14 @@ import PostgREST.Types
|
|||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
|
|
||||||
postgrest :: AppConfig -> DbStructure -> P.Pool -> Application
|
postgrest :: AppConfig -> IORef DbStructure -> P.Pool -> Application
|
||||||
postgrest conf dbStructure pool =
|
postgrest conf refDbStructure pool =
|
||||||
let middle = (if configQuiet conf then id else logStdout) . defaultMiddle in
|
let middle = (if configQuiet conf then id else logStdout) . defaultMiddle in
|
||||||
|
|
||||||
middle $ \ req respond -> do
|
middle $ \ req respond -> do
|
||||||
time <- getPOSIXTime
|
time <- getPOSIXTime
|
||||||
body <- strictRequestBody req
|
body <- strictRequestBody req
|
||||||
|
dbStructure <- readIORef refDbStructure
|
||||||
|
|
||||||
let schema = cs $ configSchema conf
|
let schema = cs $ configSchema conf
|
||||||
apiRequest = userApiRequest schema req body
|
apiRequest = userApiRequest schema req body
|
||||||
|
|||||||
+20
-11
@@ -11,6 +11,7 @@ import PostgREST.Config (AppConfig (..),
|
|||||||
import PostgREST.DbStructure
|
import PostgREST.DbStructure
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import Control.Monad.IO.Class (liftIO)
|
||||||
import Data.Monoid ((<>))
|
import Data.Monoid ((<>))
|
||||||
import Data.String.Conversions (cs)
|
import Data.String.Conversions (cs)
|
||||||
import qualified Hasql.Query as H
|
import qualified Hasql.Query as H
|
||||||
@@ -26,6 +27,7 @@ import Web.JWT (secret)
|
|||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
import System.Posix.Signals
|
import System.Posix.Signals
|
||||||
import Control.Concurrent (myThreadId)
|
import Control.Concurrent (myThreadId)
|
||||||
|
import Data.IORef
|
||||||
import Control.Exception.Base (throwTo, AsyncException(..))
|
import Control.Exception.Base (throwTo, AsyncException(..))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -58,15 +60,6 @@ main = do
|
|||||||
|
|
||||||
pool <- P.acquire (configPool conf, 10, pgSettings)
|
pool <- P.acquire (configPool conf, 10, pgSettings)
|
||||||
|
|
||||||
#ifndef mingw32_HOST_OS
|
|
||||||
tid <- myThreadId
|
|
||||||
forM_ [sigINT, sigTERM] $ \sig ->
|
|
||||||
void $ installHandler sig (Catch $ do
|
|
||||||
P.release pool
|
|
||||||
throwTo tid UserInterrupt
|
|
||||||
) Nothing
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result <- P.use pool $ do
|
result <- P.use pool $ do
|
||||||
supported <- isServerVersionSupported
|
supported <- isServerVersionSupported
|
||||||
unless supported $ error (
|
unless supported $ error (
|
||||||
@@ -74,5 +67,21 @@ main = do
|
|||||||
<> show minimumPgVersion)
|
<> show minimumPgVersion)
|
||||||
getDbStructure (cs $ configSchema conf)
|
getDbStructure (cs $ configSchema conf)
|
||||||
|
|
||||||
let dbStructure = either (error.show) id result
|
refDbStructure <- newIORef $ either (error.show) id result
|
||||||
runSettings appSettings $ postgrest conf dbStructure pool
|
|
||||||
|
#ifndef mingw32_HOST_OS
|
||||||
|
tid <- myThreadId
|
||||||
|
forM_ [sigINT, sigTERM] $ \sig ->
|
||||||
|
void $ installHandler sig (Catch $ do
|
||||||
|
P.release pool
|
||||||
|
throwTo tid UserInterrupt
|
||||||
|
) Nothing
|
||||||
|
|
||||||
|
void $ installHandler sigHUP (
|
||||||
|
Catch . void . P.use pool $ do
|
||||||
|
s <- getDbStructure (cs $ configSchema conf)
|
||||||
|
liftIO $ atomicWriteIORef refDbStructure s
|
||||||
|
) Nothing
|
||||||
|
#endif
|
||||||
|
|
||||||
|
runSettings appSettings $ postgrest conf refDbStructure pool
|
||||||
|
|||||||
+5
-4
@@ -7,6 +7,7 @@ import qualified Hasql.Pool as P
|
|||||||
|
|
||||||
import PostgREST.DbStructure (getDbStructure)
|
import PostgREST.DbStructure (getDbStructure)
|
||||||
import PostgREST.App (postgrest)
|
import PostgREST.App (postgrest)
|
||||||
|
import Data.IORef
|
||||||
import Data.String.Conversions (cs)
|
import Data.String.Conversions (cs)
|
||||||
|
|
||||||
import qualified Feature.AuthSpec
|
import qualified Feature.AuthSpec
|
||||||
@@ -27,10 +28,10 @@ main = do
|
|||||||
pool <- P.acquire (3, 10, cs testDbConn)
|
pool <- P.acquire (3, 10, cs testDbConn)
|
||||||
|
|
||||||
result <- P.use pool $ getDbStructure "test"
|
result <- P.use pool $ getDbStructure "test"
|
||||||
let dbStructure = either (error.show) id result
|
refDbStructure <- newIORef $ either (error.show) id result
|
||||||
withApp = return $ postgrest testCfg dbStructure pool
|
let withApp = return $ postgrest testCfg refDbStructure pool
|
||||||
ltdApp = return $ postgrest testLtdRowsCfg dbStructure pool
|
ltdApp = return $ postgrest testLtdRowsCfg refDbStructure pool
|
||||||
unicodeApp = return $ postgrest testUnicodeCfg dbStructure pool
|
unicodeApp = return $ postgrest testUnicodeCfg refDbStructure pool
|
||||||
|
|
||||||
hspec $ do
|
hspec $ do
|
||||||
mapM_ (beforeAll_ resetDb . before withApp) specs
|
mapM_ (beforeAll_ resetDb . before withApp) specs
|
||||||
|
|||||||
Reference in New Issue
Block a user