Skip to content

Commit 1bc3adc

Browse files
committed
bump log priorities to warning, wrap all hiedb calls in runWithDb and writerThread with retries, promote time duration and maxRetryCount constants to top level
1 parent c3fd649 commit 1bc3adc

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

ghcide/session-loader/Development/IDE/Session.hs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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
233243
runWithDb :: Logger -> FilePath -> (WithHieDb -> IndexQueue -> IO ()) -> IO ()
234244
runWithDb 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

Comments
 (0)