deal with rare SELECT ErrorBusy failures

I think they might be a sqlite bug. In discussions with sqlite devs.
This commit is contained in:
Joey Hess 2015-02-18 16:56:52 -04:00
parent af254615b2
commit 80683871ee
2 changed files with 14 additions and 7 deletions

View file

@ -96,7 +96,7 @@ addDb (FsckHandle h _) k = H.queueDb h 1000 $
sk = toSKey k
inDb :: FsckHandle -> Key -> IO Bool
inDb (FsckHandle h _) = H.queryDb h . inDb' . toSKey
inDb (FsckHandle h _) = H.queryDb h False . inDb' . toSKey
inDb' :: SKey -> SqlPersistM Bool
inDb' sk = do

View file

@ -100,13 +100,20 @@ workerThread db jobs = catchNonAsync loop showerr
- Only one action can be run at a time against a given DbHandle.
- If called concurrently in the same process, this will block until
- it is able to run.
-
- Warning: Under heavy traffic, this can fail with an exception
- that contains "ErrorBusy". WAL mode does not entirely prevent this.
- The fallback value is returned in this case.
-}
queryDb :: DbHandle -> SqlPersistM a -> IO a
queryDb (DbHandle _ jobs _) a = do
res <- newEmptyMVar
putMVar jobs $ QueryJob $
liftIO . putMVar res =<< tryNonAsync a
either throwIO return =<< takeMVar res
queryDb :: DbHandle -> a -> SqlPersistM a -> IO a
queryDb (DbHandle _ jobs _) fallback a =
catchNonAsync go (\_ -> return fallback )
where
go = do
res <- newEmptyMVar
putMVar jobs $ QueryJob $
liftIO . putMVar res =<< tryNonAsync a
either throwIO return =<< takeMVar res
closeDb :: DbHandle -> IO ()
closeDb h@(DbHandle worker jobs _) = do