@@ -199,13 +199,13 @@ retryOnSqliteBusy logger hieDb maxDelay !baseDelay !maxRetryCount rng f = do
199199 let (delay, newRng) = Random. randomR (0 , newBaseDelay) rng
200200 let newMaxRetryCount = maxRetryCount - 1
201201 liftIO $ do
202- logInfo logger $ " Retrying - " <> makeLogMsgComponentsText (Right delay) newMaxRetryCount e
202+ logWarning logger $ " Retrying - " <> makeLogMsgComponentsText (Right delay) newMaxRetryCount e
203203 threadDelay delay
204204 retryOnSqliteBusy logger hieDb maxDelay newBaseDelay newMaxRetryCount newRng f
205205
206206 | otherwise -> do
207207 liftIO $ do
208- logInfo logger $ " Retries exhausted - " <> makeLogMsgComponentsText (Left baseDelay) maxRetryCount e
208+ logWarning logger $ " Retries exhausted - " <> makeLogMsgComponentsText (Left baseDelay) maxRetryCount e
209209 throwIO e
210210
211211 Right b -> pure b
@@ -224,36 +224,53 @@ retryOnSqliteBusy logger hieDb maxDelay !baseDelay !maxRetryCount rng f = do
224224 in
225225 T. intercalate " , " logMsgComponents
226226
227+ -- | in microseconds
228+ oneSecond :: Int
229+ oneSecond = 1000000
227230
231+ -- | in microseconds
232+ oneMillisecond :: Int
233+ oneMillisecond = 1000
234+
235+ -- | default maximum number of times to retry hiedb call
236+ maxRetryCount :: Int
237+ maxRetryCount = 10
228238
229239-- | Wraps `withHieDb` to provide a database connection for reading, and a `HieWriterChan` for
230240-- writing. Actions are picked off one by one from the `HieWriterChan` and executed in serial
231241-- by a worker thread using a dedicated database connection.
232242-- This is done in order to serialize writes to the database, or else SQLite becomes unhappy
233243runWithDb :: Logger -> FilePath -> (WithHieDb -> IndexQueue -> IO () ) -> IO ()
234244runWithDb logger fp k = do
245+ -- use non-deterministic seed because maybe multiple HLS start at same time
246+ -- and send bursts of requests
247+ rng <- Random. newStdGen
235248 -- Delete the database if it has an incompatible schema version
236- withHieDb fp (const $ pure () )
249+ withHieDb fp (const ( pure () ) . makeWithRetryableHieDb rng )
237250 `Safe.catch` \ IncompatibleSchemaVersion {} -> removeFile fp
238251 withHieDb fp $ \ writedb -> do
239- initConn writedb
252+ -- the type signature is necessary to avoid concretizing the RankNType
253+ -- e.g. using it with initConn will set tyvar a to ()
254+ let withRetryableWriteDb :: WithHieDb
255+ withRetryableWriteDb = makeWithRetryableHieDb rng writedb
256+ withRetryableWriteDb initConn
257+
240258 chan <- newTQueueIO
241- -- use newStdGen because what if multiple HLS start at same time and send bursts of requests
242- rng <- Random. newStdGen
243- withAsync (writerThread writedb chan rng) $ \ _ -> do
244- withHieDb fp (\ readDb -> k (retryOnSqliteBusy logger readDb oneSecond oneMillisecond maxRetryCount rng) chan)
259+
260+ withAsync (writerThread withRetryableWriteDb chan) $ \ _ -> do
261+ withHieDb fp (\ readDb -> k (makeWithRetryableHieDb rng readDb) chan)
245262 where
246- oneSecond = 1000000
247- oneMillisecond = 1000
248- maxRetryCount = 10
263+ makeWithRetryableHieDb :: RandomGen g => g -> HieDb -> WithHieDb
264+ makeWithRetryableHieDb rng hieDb = retryOnSqliteBusy logger hieDb oneSecond oneMillisecond maxRetryCount rng
249265
250- writerThread db chan rng = do
266+ writerThread :: WithHieDb -> IndexQueue -> IO ()
267+ writerThread withRetryableWriteDb chan = do
251268 -- Clear the index of any files that might have been deleted since the last run
252- deleteMissingRealFiles db
253- _ <- garbageCollectTypeNames db
269+ _ <- withRetryableWriteDb deleteMissingRealFiles
270+ _ <- withRetryableWriteDb garbageCollectTypeNames
254271 forever $ do
255272 k <- atomically $ readTQueue chan
256- k (retryOnSqliteBusy logger db oneSecond oneMillisecond maxRetryCount rng)
273+ k withRetryableWriteDb
257274 `Safe.catch` \ e@ SQLError {} -> do
258275 logDebug logger $ T. pack $ " SQLite error in worker, ignoring: " ++ show e
259276 `Safe.catchAny` \ e -> do
0 commit comments