Skip to content

Commit

Permalink
fix: listener silent fail on replica
Browse files Browse the repository at this point in the history
Update hasql-notifications to include the fix on
diogob/hasql-notifications#24.

Which now reveals the following error:

```
$ postgrest-with-postgresql-16 --replica -f test/spec/fixtures/load.sql postgrest-run

17/May/2024:18:35:38 -0500: Successfully connected to PostgreSQL 16.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 13.2.0, 64-bit
17/May/2024:18:35:38 -0500: Could not listen for notifications on the "pgrst" channel. ERROR:  cannot execute LISTEN during recovery
17/May/2024:18:35:38 -0500: Retrying listening for notifications...
```

This is still not good because the LISTEN channel will be retried
forever without a backoff.
  • Loading branch information
steve-chavez committed May 19, 2024
1 parent aa75412 commit 756aad7
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #3424, Admin `/live` and `/ready` now differentiates a failure as 500 status - @steve-chavez
+ 503 status is still given when postgREST is in a recovering state
- #3478, Media Types are parsed case insensitively - @develop7
- #2781, Fix listener silently failing on read replica - @steve-chavez

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion cabal.project.freeze
Original file line number Diff line number Diff line change
@@ -1 +1 @@
index-state: hackage.haskell.org 2024-04-15T20:28:44Z
index-state: hackage.haskell.org 2024-05-17T23:41:49Z
6 changes: 3 additions & 3 deletions nix/overlays/haskell-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ let
# Notes:
# - When adding a new package version here, update cabal.
# + Update postgrest.cabal with the package version
# + Update cabal.project.freeze. Just set it to the current timestamp then run `cabal build`. It will tell you the correct timestamp for the index state.
# + Update the index-state in cabal.project.freeze. Run `cabal update` which should return the latest index state.
# - When adding a new package version here, you have to update stack.
# + To update stack.yaml add:
# extra-deps:
Expand Down Expand Up @@ -67,8 +67,8 @@ let
hasql-notifications = lib.dontCheck (prev.callHackageDirect
{
pkg = "hasql-notifications";
ver = "0.2.1.1";
sha256 = "sha256-oPhKA/pSQGJvgQyhsi7CVr9iDT7uWpKUz0iJfXsaxXo=";
ver = "0.2.2.0";
sha256 = "sha256-73OQ9/su2qvO7HavF3xuuNWLXSXyB9reBUQDaHys06I=";
}
{ }
);
Expand Down
2 changes: 1 addition & 1 deletion postgrest.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ library
, gitrev >= 1.2 && < 1.4
, hasql >= 1.6.1.1 && < 1.7
, hasql-dynamic-statements >= 0.3.1 && < 0.4
, hasql-notifications >= 0.2.1.1 && < 0.3
, hasql-notifications >= 0.2.2.0 && < 0.3
, hasql-pool >= 1.0.1 && < 1.1
, hasql-transaction >= 1.0.1 && < 1.1
, heredoc >= 0.2 && < 0.3
Expand Down
10 changes: 6 additions & 4 deletions src/PostgREST/AppState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -542,23 +542,25 @@ listener appState@AppState{stateObserver=observer, stateMainThreadId=mainThreadI
dbOrError <- acquire $ toUtf8 (addFallbackAppName prettyVersion configDbUri)
case dbOrError of
Right db -> do
observer $ DBListenerStart dbChannel
SQL.listen db $ SQL.toPgIdentifier dbChannel
observer $ DBListenStart dbChannel
SQL.waitForNotifications handleNotification db

Left err -> do
observer $ DBListenerFail dbChannel err
observer $ DBListenFail dbChannel (Left err)
exitFailure
where
handleFinally dbChannel False err = do
observer $ DBListenerFailRecoverObs False dbChannel err
observer $ DBListenFail dbChannel (Right err)
killThread mainThreadId
handleFinally dbChannel True err = do
-- if the thread dies, we try to recover
observer $ DBListenerFailRecoverObs True dbChannel err
observer $ DBListenFail dbChannel (Right err)
-- assume the pool connection was also lost, call the connection worker
connectionWorker appState

-- retry the listener
observer DBListenRetry
listener appState conf

handleNotification channel msg =
Expand Down
20 changes: 12 additions & 8 deletions src/PostgREST/Observation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ data Observation
| SchemaCacheLoadedObs Double
| ConnectionRetryObs Int
| ConnectionPgVersionErrorObs SQL.UsageError
| DBListenerStart Text
| DBListenerFail Text SQL.ConnectionError
| DBListenerFailRecoverObs Bool Text (Either SomeException ())
| DBListenStart Text
| DBListenFail Text (Either SQL.ConnectionError (Either SomeException ()))
| DBListenRetry
| DBListenerGotSCacheMsg ByteString
| DBListenerGotConfigMsg ByteString
| ConfigReadErrorObs SQL.UsageError
Expand Down Expand Up @@ -97,12 +97,16 @@ observationMessage = \case
"Attempting to reconnect to the database in " <> (show delay::Text) <> " seconds..."
ConnectionPgVersionErrorObs usageErr ->
jsonMessage usageErr
DBListenerStart channel -> do
DBListenStart channel -> do
"Listening for notifications on the " <> show channel <> " channel"
DBListenerFail channel err -> do
"Could not listen for notifications on the " <> channel <> " channel. " <> show err
DBListenerFailRecoverObs recover channel err ->
"Could not listen for notifications on the " <> channel <> " channel. " <> showListenerError err <> (if recover then " Retrying listening for notifications.." else mempty)
DBListenFail channel listenErr ->
"Failed listening for notifications on the " <> show channel <> " channel. " <> (
case listenErr of
Left err -> show err
Right err -> showListenerError err
)
DBListenRetry ->
"Retrying listening for notifications..."
DBListenerGotSCacheMsg channel ->
"Received a schema cache reload message on the " <> show channel <> " channel"
DBListenerGotConfigMsg channel ->
Expand Down
1 change: 1 addition & 0 deletions stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ nix:

extra-deps:
- fuzzyset-0.2.4
- hasql-notifications-0.2.2.0
- hasql-pool-1.0.1
7 changes: 7 additions & 0 deletions stack.yaml.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ packages:
size: 574
original:
hackage: fuzzyset-0.2.4
- completed:
hackage: hasql-notifications-0.2.2.0@sha256:a4e591ef3f06647b056567d3b66948c4a85371f05deb5434edb6ce190f7c845d,2021
pantry-tree:
sha256: bd7192a5e82ef6dbac711c3433408a0330c8db1cd3482be1ccd4fbd0a63bc2f6
size: 452
original:
hackage: hasql-notifications-0.2.2.0
- completed:
hackage: hasql-pool-1.0.1@sha256:3cfb4c7153a6c536ac7e126c17723e6d26ee03794954deed2d72bcc826d05a40,2302
pantry-tree:
Expand Down

0 comments on commit 756aad7

Please sign in to comment.