More robust handling of ErrorBusy when writing to sqlite databases
While ErrorBusy and other exceptions were caught and the write retried for up to 10 seconds, it was still possible for git-annex to eventually give up and error out without writing to the database. Now it will retry as long as necessary. This does mean that, if one git-annex process is suspended just as sqlite has locked the database for writing, another git-annex that tries to write it it might get stuck retrying forever. But, that could already happen when opening the sqlite database, which retries forever on ErrorBusy. This is an area where git-annex is known to not behave well, there's a todo about the general case of it. Sponsored-by: Dartmouth College's Datalad project
This commit is contained in:
parent
0d762acf7e
commit
3149a1e2fe
4 changed files with 120 additions and 22 deletions
|
@ -82,22 +82,20 @@ queryDb (DbHandle _ jobs) a = do
|
|||
|
||||
{- Writes a change to the database.
|
||||
-
|
||||
- Writes can fail if another write is happening concurrently.
|
||||
- So write failures are caught and retried repeatedly for up to 10
|
||||
- seconds, which should avoid all but the most exceptional problems.
|
||||
- Writes can fail when another write is happening concurrently.
|
||||
- So write failures are caught and retried repeatedly.
|
||||
-}
|
||||
commitDb :: DbHandle -> SqlPersistM () -> IO ()
|
||||
commitDb h wa = robustly Nothing 100 (commitDb' h wa)
|
||||
commitDb h wa = robustly (commitDb' h wa)
|
||||
where
|
||||
robustly :: Maybe SomeException -> Int -> IO (Either SomeException ()) -> IO ()
|
||||
robustly e 0 _ = error $ "failed to commit changes to sqlite database: " ++ show e
|
||||
robustly _ n a = do
|
||||
robustly :: IO (Either SomeException ()) -> IO ()
|
||||
robustly a = do
|
||||
r <- a
|
||||
case r of
|
||||
Right _ -> return ()
|
||||
Left e -> do
|
||||
Left _ -> do
|
||||
threadDelay 100000 -- 1/10th second
|
||||
robustly (Just e) (n-1) a
|
||||
robustly a
|
||||
|
||||
commitDb' :: DbHandle -> SqlPersistM () -> IO (Either SomeException ())
|
||||
commitDb' (DbHandle _ jobs) a = do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue