fix: Flush pool as late as possible during schema cache reloading (#4645)

retryingSchemaCacheLoad flushes the pool upon every retry before it starts reloading the schema. This is too early as schema reloading might take some time during which new connections might be acquired. The consequence is that:
* upon successful schema cache reload we might have some connections created with the old schema cache
* we close connections upon each retry and under load we will keep closing and re-opening connections until schema cache load succeeds

This change is to make sure we flush the pool only after successful schema cache querying but before loading (so that connections acquired during loading wait for it and do not interfere with timing the loading process).
This commit is contained in:
Michal Kleczek
2026-04-14 17:09:25 -05:00
committed by GitHub
parent 4ca34c0695
commit aca58c8571
4 changed files with 14 additions and 10 deletions
+4 -2
View File
@@ -302,8 +302,6 @@ retryingSchemaCacheLoad appState@AppState{stateObserver=observer, stateMainThrea
let delay = fromMaybe 0 rsPreviousDelay `div` oneSecondInUs
observer $ ConnectionRetryObs delay
flushPool appState
(,) <$> qPgVersion <*> (qInDbConfig *> qSchemaCache)
)
where
@@ -352,6 +350,10 @@ retryingSchemaCacheLoad appState@AppState{stateObserver=observer, stateMainThrea
-- IORef on putSchemaCache. This is why schema cache status is marked as pending here to signal the Admin server (using isPending) that we're on a recovery state.
markSchemaCachePending appState
putSchemaCache appState $ Just sCache
-- Flush the pool after loading the schema cache to reset any stale session cache entries
-- We do it after successfully querying the schema cache (because this can fail and during retries we would flush the pool repeatedly unnecessarily)
-- and after marking sCacheStatus as pending,
flushPool appState
observer $ SchemaCacheQueriedObs resultTime
observer . uncurry SchemaCacheLoadedObs =<< timeItT (evaluate $ showSummary sCache)
markSchemaCacheLoaded appState