refactor: make nextListenerDelay local to Listener module
Right now stateNextListenerDelay is only used in Listener module. This change is a small refactoring moving nextListenerDelay to Listener to increase cohesion and decrease coupling.
This commit is contained in:
committed by
Wolfgang Walther
parent
2976eb047b
commit
fae6253932
@@ -11,13 +11,11 @@ module PostgREST.AppState
|
|||||||
, getMainThreadId
|
, getMainThreadId
|
||||||
, getPgVersion
|
, getPgVersion
|
||||||
, getNextDelay
|
, getNextDelay
|
||||||
, getNextListenerDelay
|
|
||||||
, getTime
|
, getTime
|
||||||
, getJwtCacheState
|
, getJwtCacheState
|
||||||
, init
|
, init
|
||||||
, initWithPool
|
, initWithPool
|
||||||
, putConfig -- For tests TODO refactoring
|
, putConfig -- For tests TODO refactoring
|
||||||
, putNextListenerDelay
|
|
||||||
, putSchemaCache
|
, putSchemaCache
|
||||||
, putPgVersion
|
, putPgVersion
|
||||||
, putIsListenerOn
|
, putIsListenerOn
|
||||||
@@ -91,8 +89,6 @@ data AppState = AppState
|
|||||||
, stateMainThreadId :: ThreadId
|
, stateMainThreadId :: ThreadId
|
||||||
-- | Keeps track of the next delay for db connection retry
|
-- | Keeps track of the next delay for db connection retry
|
||||||
, stateNextDelay :: IORef Int
|
, stateNextDelay :: IORef Int
|
||||||
-- | Keeps track of the next delay for the listener
|
|
||||||
, stateNextListenerDelay :: IORef Int
|
|
||||||
-- | Observation handler
|
-- | Observation handler
|
||||||
, stateObserver :: ObservationHandler
|
, stateObserver :: ObservationHandler
|
||||||
-- | JWT Cache
|
-- | JWT Cache
|
||||||
@@ -131,7 +127,6 @@ initWithPool pool conf loggerState metricsState observer = mdo
|
|||||||
<*> mkAutoUpdate defaultUpdateSettings { updateAction = getCurrentTime }
|
<*> mkAutoUpdate defaultUpdateSettings { updateAction = getCurrentTime }
|
||||||
<*> myThreadId
|
<*> myThreadId
|
||||||
<*> newIORef 0
|
<*> newIORef 0
|
||||||
<*> newIORef 1
|
|
||||||
<*> pure observer
|
<*> pure observer
|
||||||
<*> JwtCache.init conf observer
|
<*> JwtCache.init conf observer
|
||||||
<*> pure loggerState
|
<*> pure loggerState
|
||||||
@@ -248,12 +243,6 @@ schemaCacheLoader = debouncedSCacheLoader
|
|||||||
getNextDelay :: AppState -> IO Int
|
getNextDelay :: AppState -> IO Int
|
||||||
getNextDelay = readIORef . stateNextDelay
|
getNextDelay = readIORef . stateNextDelay
|
||||||
|
|
||||||
getNextListenerDelay :: AppState -> IO Int
|
|
||||||
getNextListenerDelay = readIORef . stateNextListenerDelay
|
|
||||||
|
|
||||||
putNextListenerDelay :: AppState -> Int -> IO ()
|
|
||||||
putNextListenerDelay = atomicWriteIORef . stateNextListenerDelay
|
|
||||||
|
|
||||||
getConfig :: AppState -> IO AppConfig
|
getConfig :: AppState -> IO AppConfig
|
||||||
getConfig = readIORef . stateConf
|
getConfig = readIORef . stateConf
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import qualified PostgREST.Config as Config
|
|||||||
import Control.Arrow ((&&&))
|
import Control.Arrow ((&&&))
|
||||||
import Data.Bitraversable (bisequence)
|
import Data.Bitraversable (bisequence)
|
||||||
import Data.Either.Combinators (whenRight)
|
import Data.Either.Combinators (whenRight)
|
||||||
|
import Data.IORef (IORef, newIORef,
|
||||||
|
readIORef, writeIORef)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Database.PostgreSQL.LibPQ as LibPQ
|
import qualified Database.PostgreSQL.LibPQ as LibPQ
|
||||||
import qualified Hasql.Session as SQL
|
import qualified Hasql.Session as SQL
|
||||||
@@ -29,13 +31,14 @@ import Protolude
|
|||||||
runListener :: AppState -> IO ()
|
runListener :: AppState -> IO ()
|
||||||
runListener appState = do
|
runListener appState = do
|
||||||
AppConfig{..} <- getConfig appState
|
AppConfig{..} <- getConfig appState
|
||||||
when configDbChannelEnabled $
|
when configDbChannelEnabled $ do
|
||||||
void . forkIO . void $ retryingListen appState False
|
nextDelay <- newIORef 1
|
||||||
|
void . forkIO . void $ retryingListen appState nextDelay False
|
||||||
|
|
||||||
-- | Starts a LISTEN connection and handles notifications. It recovers with exponential backoff with a cap of 32 seconds, if the LISTEN connection is lost.
|
-- | Starts a LISTEN connection and handles notifications. It recovers with exponential backoff with a cap of 32 seconds, if the LISTEN connection is lost.
|
||||||
-- | This function never returns (but can throw) and return type enforces that.
|
-- | This function never returns (but can throw) and return type enforces that.
|
||||||
retryingListen :: AppState -> Bool -> IO Void
|
retryingListen :: AppState -> IORef Int -> Bool -> IO Void
|
||||||
retryingListen appState hasDbListenerBug = do
|
retryingListen appState nextDelay hasDbListenerBug = do
|
||||||
cfg@AppConfig{..} <- AppState.getConfig appState
|
cfg@AppConfig{..} <- AppState.getConfig appState
|
||||||
let
|
let
|
||||||
dbChannel = toS configDbChannel
|
dbChannel = toS configDbChannel
|
||||||
@@ -48,13 +51,13 @@ retryingListen appState hasDbListenerBug = do
|
|||||||
killThread mainThreadId
|
killThread mainThreadId
|
||||||
|
|
||||||
-- retry the listener
|
-- retry the listener
|
||||||
delay <- AppState.getNextListenerDelay appState
|
delay <- readIORef nextDelay
|
||||||
observer $ DBListenRetry delay
|
observer $ DBListenRetry delay
|
||||||
threadDelay (delay * oneSecondInMicro)
|
threadDelay (delay * oneSecondInMicro)
|
||||||
unless (delay == maxDelay) $
|
unless (delay == maxDelay) $
|
||||||
AppState.putNextListenerDelay appState (delay * 2)
|
writeIORef nextDelay (delay * 2)
|
||||||
-- loop running the listener
|
-- loop running the listener
|
||||||
retryingListen appState (isDbListenerBug err)
|
retryingListen appState nextDelay (isDbListenerBug err)
|
||||||
|
|
||||||
-- Execute the listener with error handling
|
-- Execute the listener with error handling
|
||||||
handle onError $ do
|
handle onError $ do
|
||||||
@@ -75,12 +78,12 @@ retryingListen appState hasDbListenerBug = do
|
|||||||
|
|
||||||
AppState.putIsListenerOn appState True
|
AppState.putIsListenerOn appState True
|
||||||
|
|
||||||
delay <- AppState.getNextListenerDelay appState
|
delay <- readIORef nextDelay
|
||||||
when (delay > 1) $ do -- if we did a retry
|
when (delay > 1) $ do -- if we did a retry
|
||||||
-- assume we lost notifications, refresh the schema cache
|
-- assume we lost notifications, refresh the schema cache
|
||||||
AppState.schemaCacheLoader appState
|
AppState.schemaCacheLoader appState
|
||||||
-- reset the delay
|
-- reset the delay
|
||||||
AppState.putNextListenerDelay appState 1
|
writeIORef nextDelay 1
|
||||||
|
|
||||||
observer $ DBListenStart pqHost pqPort pgFullName dbChannel
|
observer $ DBListenStart pqHost pqPort pgFullName dbChannel
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user