Skip to content

Commit

Permalink
feat: /ready pending state as 503 and 500 as fail
Browse files Browse the repository at this point in the history
BREAKING CHANGE

The /ready and /live endpoints now reply with 500 instead of 503 for
failure. 503 is a transient state that PostgREST can recover from.
  • Loading branch information
steve-chavez committed May 7, 2024
1 parent 515154a commit de933a6
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
+ Shows the correct JSON format in the `hints` field
- #3340, Log when the LISTEN channel gets a notification - @steve-chavez
- #3184, Log full pg version to stderr on connection - @steve-chavez
- #3424, Admin `/ready` endpoint now differentiates a failure as 500 and a recovering state with 503 - @steve-chavez

### Fixed

Expand All @@ -47,6 +48,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- `Prefer: params=single-object` is deprecated. Use [a function with a single unnamed JSON parameter](https://postgrest.org/en/latest/references/api/stored_procedures.html#s-proc-single-json) instead. - @steve-chavez

### Changed

- #3424, Admin `/ready` endpoint now responds with 500 on failure and will respond with 503 while PostgREST is in progress of recovering connection or loading its schema cache - @steve-chavez

### Documentation

- #3289, Add dark mode. Can be toggled by a button in the bottom right corner. - @laurenceisla
Expand Down
13 changes: 10 additions & 3 deletions src/PostgREST/Admin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,19 @@ admin :: AppState.AppState -> Wai.Application
admin appState req respond = do
isMainAppReachable <- isRight <$> reachMainApp (AppState.getSocketREST appState)
isLoaded <- AppState.isLoaded appState
isPending <- AppState.isPending appState

case Wai.pathInfo req of
["ready"] ->
respond $ Wai.responseLBS (if isMainAppReachable && isLoaded then HTTP.status200 else HTTP.status503) [] mempty
["live"] ->
respond $ Wai.responseLBS (if isMainAppReachable then HTTP.status200 else HTTP.status503) [] mempty
respond $ Wai.responseLBS (if isMainAppReachable then HTTP.status200 else HTTP.status500) [] mempty
["ready"] ->
let
status | not isMainAppReachable = HTTP.status500
| isPending = HTTP.status503
| isLoaded = HTTP.status200
| otherwise = HTTP.status500
in
respond $ Wai.responseLBS status [] mempty
["config"] -> do
config <- AppState.getConfig appState
respond $ Wai.responseLBS HTTP.status200 [] (LBS.fromStrict $ encodeUtf8 $ Config.toText config)
Expand Down
7 changes: 7 additions & 0 deletions src/PostgREST/AppState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module PostgREST.AppState
, runListener
, getObserver
, isLoaded
, isPending
) where

import qualified Data.Aeson as JSON
Expand Down Expand Up @@ -315,6 +316,12 @@ isLoaded x = do
connEstablished <- isConnEstablished x
return $ scacheStatus == SCLoaded && connEstablished

isPending :: AppState -> IO Bool
isPending x = do
scacheStatus <- readIORef $ stateSCacheStatus x
connStatus <- readIORef $ stateConnStatus x
return $ scacheStatus == SCPending || connStatus == ConnPending

putSCacheStatus :: AppState -> SchemaCacheStatus -> IO ()
putSCacheStatus = atomicWriteIORef . stateSCacheStatus

Expand Down
4 changes: 2 additions & 2 deletions test/io/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ def test_admin_ready_dependent_on_main_app(defaultenv):
# delete the unix socket to make the main app fail
os.remove(defaultenv["PGRST_SERVER_UNIX_SOCKET"])
response = postgrest.admin.get("/ready")
assert response.status_code == 503
assert response.status_code == 500


def test_admin_live_good(defaultenv):
Expand All @@ -757,7 +757,7 @@ def test_admin_live_dependent_on_main_app(defaultenv):
# delete the unix socket to make the main app fail
os.remove(defaultenv["PGRST_SERVER_UNIX_SOCKET"])
response = postgrest.admin.get("/live")
assert response.status_code == 503
assert response.status_code == 500


@pytest.mark.parametrize("specialhostvalue", FIXTURES["specialhostvalues"])
Expand Down

0 comments on commit de933a6

Please sign in to comment.