Skip to content

Commit

Permalink
wip: force read-write for listener connection
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-chavez committed May 2, 2024
1 parent d9a51f2 commit 2bae001
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/PostgREST/AppState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import Data.Time.Clock (UTCTime, getCurrentTime)

import PostgREST.Config (AppConfig (..),
addFallbackAppName,
addTargetSessionAttrs,
readAppConfig)
import PostgREST.Config.Database (queryDbSettings,
queryPgVersion,
Expand Down Expand Up @@ -499,7 +500,8 @@ listener appState@AppState{stateObserver=observer} conf@AppConfig{..} = do

-- forkFinally allows to detect if the thread dies
void . flip forkFinally (handleFinally dbChannel configDbPoolAutomaticRecovery) $ do
dbOrError <- acquire $ toUtf8 (addFallbackAppName prettyVersion configDbUri)
let connString = addTargetSessionAttrs $ addFallbackAppName prettyVersion configDbUri
dbOrError <- acquire $ toUtf8 connString
case dbOrError of
Right db -> do
observer $ DBListenerStart dbChannel
Expand Down
26 changes: 26 additions & 0 deletions src/PostgREST/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module PostgREST.Config
, toURI
, parseSecret
, addFallbackAppName
, addTargetSessionAttrs
) where

import qualified Crypto.JOSE.Types as JOSE
Expand Down Expand Up @@ -518,3 +519,28 @@ addFallbackAppName version dbUri = dbUri <>
uriFmt = pKeyWord <> toS (escapeURIString isUnescapedInURIComponent $ toS pgrstVer)
pKeyWord = "fallback_application_name="
pgrstVer = "PostgREST " <> T.decodeUtf8 version


-- | Adds `target_session_attrs=read-write` to the connection string. This allows using PostgREST listener when multiple hosts are specified in the connection string.
--
-- >>> addTargetSessionAttrs "postgres:///postgres?host=/dir/0kN/socket_replica_24378,/dir/0kN/socket"
-- "postgres:///postgres?host=/dir/0kN/socket_replica_24378,/dir/0kN/socket&target_session_attrs=read-write"
--
-- >>> addTargetSessionAttrs "postgresql://host1:123,host2:456/somedb"
-- "postgresql://host1:123,host2:456/somedb?target_session_attrs=read-write"
--
-- >>> addTargetSessionAttrs "postgresql://host1:123,host2:456/somedb?fallback_application_name=foo"
-- "postgresql://host1:123,host2:456/somedb?fallback_application_name=foo&target_session_attrs=read-write"
--
-- >>> addTargetSessionAttrs "invalid_uri1=val1 invalid_uri2=val2"
-- "invalid_uri1=val1 invalid_uri2=val2"
addTargetSessionAttrs :: Text -> Text
addTargetSessionAttrs dbUri = dbUri <>
case uriQuery <$> parseURI (toS dbUri) of
-- Don't do anything to key=val connection strings or invalid URIs
Nothing -> mempty
Just "" -> "?" <> part
Just "?" -> part
_ -> "&" <> part
where
part = "target_session_attrs=read-write"

0 comments on commit 2bae001

Please sign in to comment.