diff --git a/CHANGELOG.md b/CHANGELOG.md index d35d8febb..95e05f2b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. From versio ## Unreleased +### Added + +- Log a `HINT` when the LISTEN channel stops working due to a PostgreSQL bug by @laurenceisla in #4581 + ## [14.7] - 2026-03-20 ### Fixed diff --git a/src/PostgREST/Listener.hs b/src/PostgREST/Listener.hs index a551082c3..a5d12aa1a 100644 --- a/src/PostgREST/Listener.hs +++ b/src/PostgREST/Listener.hs @@ -10,7 +10,8 @@ import qualified Hasql.Connection as SQL import qualified Hasql.Notifications as SQL import PostgREST.AppState (AppState, getConfig) import PostgREST.Config (AppConfig (..)) -import PostgREST.Observation (Observation (..)) +import PostgREST.Observation (Observation (..), + isDbListenerBug) import PostgREST.Version (prettyVersion) import qualified PostgREST.AppState as AppState @@ -36,6 +37,8 @@ retryingListen appState = do onError err = do AppState.putIsListenerOn appState False observer $ DBListenFail dbChannel (Right err) + when (isDbListenerBug err) $ + observer DBListenBugHint unless configDbPoolAutomaticRecovery $ killThread mainThreadId diff --git a/src/PostgREST/Observation.hs b/src/PostgREST/Observation.hs index 3acadf961..8c033f176 100644 --- a/src/PostgREST/Observation.hs +++ b/src/PostgREST/Observation.hs @@ -13,6 +13,7 @@ module PostgREST.Observation , observationMessage , ObservationHandler , showOnSingleLine + , isDbListenerBug ) where import qualified Data.ByteString.Lazy as LBS @@ -47,6 +48,7 @@ data Observation | DBListenStart Text | DBListenFail Text (Either SQL.ConnectionError SomeException) | DBListenRetry Int + | DBListenBugHint -- https://github.com/PostgREST/postgrest/issues/3147 | DBListenerGotSCacheMsg ByteString | DBListenerGotConfigMsg ByteString | DBListenerConnectionCleanupFail SomeException @@ -119,6 +121,8 @@ observationMessage = \case either showListenerConnError showListenerException listenErr DBListenRetry delay -> "Retrying listening for database notifications in " <> (show delay::Text) <> " seconds..." + DBListenBugHint -> + "HINT: This is likely a bug in the notification queue, try executing the following to solve it: select pg_notification_queue_usage();" DBListenerGotSCacheMsg channel -> "Received a schema cache reload message on the " <> show channel <> " channel" DBListenerGotConfigMsg channel -> @@ -181,3 +185,6 @@ observationMessage = \case showOnSingleLine :: Char -> Text -> Text showOnSingleLine split txt = T.intercalate " " $ T.filter (/= split) <$> T.lines txt -- the errors from hasql-notifications come intercalated with "\t\n" + +isDbListenerBug :: SomeException -> Bool +isDbListenerBug e = "could not access status of transaction" `T.isInfixOf` show e