From ee8b3ef8fee8560ae224dbcbdadb229dce76c972 Mon Sep 17 00:00:00 2001 From: steve-chavez Date: Tue, 19 Mar 2024 00:46:43 -0500 Subject: [PATCH] fix: log on LISTEN notification --- CHANGELOG.md | 2 +- src/PostgREST/AppState.hs | 12 +++++++----- src/PostgREST/Observation.hs | 8 +++++++- test/io/test_io.py | 2 ++ 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26f1d7eb6..355fc872f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #3237, Dump media handlers and timezones with --dump-schema - @wolfgangwalther - #3323, #3324, Don't hide error on LISTEN channel failure - @steve-chavez - #3330, Incorrect admin server `/ready` response on slow schema cache loads - @steve-chavez - - #3327, Fix slow responses on schema cache reloads - @steve-chavez + - #3340, Log when the LISTEN channel gets a notification - @steve-chavez ### Deprecated diff --git a/src/PostgREST/AppState.hs b/src/PostgREST/AppState.hs index 4ec78f692..29059c073 100644 --- a/src/PostgREST/AppState.hs +++ b/src/PostgREST/AppState.hs @@ -1,4 +1,5 @@ {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE RecordWildCards #-} @@ -501,6 +502,7 @@ listener appState observer = do putIsListenerOn appState True SQL.listen db $ SQL.toPgIdentifier dbChannel SQL.waitForNotifications handleNotification db + Left err -> do observer $ DBListenerFail dbChannel err exitFailure @@ -517,11 +519,11 @@ listener appState observer = do -- retry the listener listener appState observer - handleNotification _ msg - | BS.null msg = cacheReloader - | msg == "reload schema" = cacheReloader - | msg == "reload config" = reReadConfig False appState observer - | otherwise = pure () -- Do nothing if anything else than an empty message is sent + handleNotification channel msg = + if | BS.null msg -> observer (DBListenerGotSCacheMsg channel) >> cacheReloader + | msg == "reload schema" -> observer (DBListenerGotSCacheMsg channel) >> cacheReloader + | msg == "reload config" -> observer (DBListenerGotConfigMsg channel) >> reReadConfig False appState observer + | otherwise -> pure () -- Do nothing if anything else than an empty message is sent cacheReloader = -- reloads the schema cache + restarts pool connections diff --git a/src/PostgREST/Observation.hs b/src/PostgREST/Observation.hs index 98370ef98..de0396539 100644 --- a/src/PostgREST/Observation.hs +++ b/src/PostgREST/Observation.hs @@ -40,6 +40,8 @@ data Observation | DBListenerStart Text | DBListenerFail Text SQL.ConnectionError | DBListenerFailRecoverObs Bool Text (Either SomeException ()) + | DBListenerGotSCacheMsg ByteString + | DBListenerGotConfigMsg ByteString | ConfigReadErrorObs | ConfigReadErrorFatalObs SQL.UsageError Text | ConfigReadErrorNotFatalObs SQL.UsageError @@ -82,11 +84,15 @@ observationMessage = \case ConnectionPgVersionErrorObs usageErr -> jsonMessage usageErr DBListenerStart channel -> do - "Listening for notifications on the " <> channel <> " channel" + "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) + DBListenerGotSCacheMsg channel -> + "Received a schema cache reload message on the " <> show channel <> " channel" + DBListenerGotConfigMsg channel -> + "Received a config reload message on the " <> show channel <> " channel" ConfigReadErrorObs -> "An error ocurred when trying to query database settings for the config parameters" ConfigReadErrorFatalObs usageErr hint -> diff --git a/test/io/test_io.py b/test/io/test_io.py index ca4211502..d35fdb6b8 100644 --- a/test/io/test_io.py +++ b/test/io/test_io.py @@ -421,6 +421,8 @@ def test_invalid_role_claim_key_notify_reload(defaultenv): with run(env=env) as postgrest: postgrest.session.post("/rpc/invalid_role_claim_key_reload") + output = postgrest.read_stdout() + assert 'Received a config reload message on the "pgrst" channel' in output[0] output = postgrest.read_stdout() assert "failed to parse role-claim-key value" in output[0]