fix STM crash

git-annex: thread blocked indefinitely in an STM transaction
failed

git-annex: sqlite query crashed
CallStack (from HasCallStack):
  error, called at ./Database/Handle.hs:98:42 in main:Database.Handle
failed

This needs further investigation.
This commit is contained in:
Joey Hess 2019-03-05 16:29:22 -04:00
parent 46d33e804a
commit dc278c059c
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 20 additions and 12 deletions

View file

@ -260,7 +260,8 @@ adjustExportImport r = case M.lookup "exporttree" (config r) of
lcklckv <- liftIO newEmptyTMVarIO lcklckv <- liftIO newEmptyTMVarIO
dbv <- liftIO newEmptyTMVarIO dbv <- liftIO newEmptyTMVarIO
exportinconflict <- liftIO $ newTVarIO False exportinconflict <- liftIO $ newTVarIO False
return (dbv, lcklckv, exportinconflict) exportupdated <- liftIO $ newTMVarIO ()
return (dbv, lcklckv, exportinconflict, exportupdated)
-- Only open the database once it's needed, and take an -- Only open the database once it's needed, and take an
-- exclusive write lock. The write lock will then remain -- exclusive write lock. The write lock will then remain
@ -280,14 +281,13 @@ adjustExportImport r = case M.lookup "exporttree" (config r) of
, liftIO $ fst <$> atomically (readTMVar dbtv) , liftIO $ fst <$> atomically (readTMVar dbtv)
) )
getexportdb (dbv, lcklckv, exportinconflict) = getexportdb (dbv, lcklckv, _, _) =
liftIO (atomically (tryReadTMVar dbv)) >>= \case liftIO (atomically (tryReadTMVar dbv)) >>= \case
Just db -> return db Just db -> return db
-- let only one thread take the lock -- let only one thread take the lock
Nothing -> ifM (liftIO $ atomically $ tryPutTMVar lcklckv ()) Nothing -> ifM (liftIO $ atomically $ tryPutTMVar lcklckv ())
( do ( do
db <- Export.openDb (uuid r) db <- Export.openDb (uuid r)
updateexportdb db exportinconflict
liftIO $ atomically $ putTMVar dbv db liftIO $ atomically $ putTMVar dbv db
return db return db
-- loser waits for winner to open the db and -- loser waits for winner to open the db and
@ -295,21 +295,24 @@ adjustExportImport r = case M.lookup "exporttree" (config r) of
, liftIO $ atomically (readTMVar dbv) , liftIO $ atomically (readTMVar dbv)
) )
getexportinconflict (_, _, v) = v getexportinconflict (_, _, v, _) = v
-- Check if the export log is different than the database and -- Check once if the export log is different than the database and
-- updates the database, to notice when an export has been -- updates the database, to notice when an export has been
-- updated from another repository. -- updated from another repository.
updateexportdb db exportinconflict = updateexportdb db (_, _, exportinconflict, exportupdated) =
Export.updateExportTreeFromLog db >>= \case liftIO (atomically (tryTakeTMVar exportupdated)) >>= \case
Export.ExportUpdateSuccess -> return () Just () -> Export.updateExportTreeFromLog db >>= \case
Export.ExportUpdateConflict -> do Export.ExportUpdateSuccess -> return ()
warnExportConflict r Export.ExportUpdateConflict -> do
liftIO $ atomically $ warnExportConflict r
writeTVar exportinconflict True liftIO $ atomically $
writeTVar exportinconflict True
Nothing -> return ()
getexportlocs dbv k = do getexportlocs dbv k = do
db <- getexportdb dbv db <- getexportdb dbv
updateexportdb db dbv
liftIO $ Export.getExportTree db k liftIO $ Export.getExportTree db k
retrieveKeyFileFromExport dbv k _af dest p = unVerified $ retrieveKeyFileFromExport dbv k _af dest p = unVerified $

View file

@ -10,6 +10,11 @@ this.
## implementation notes ## implementation notes
* tracking branch is updated after a failed export, should not be
* getknowncids should run "updateexportdb exportdb exportdbv",
but that leads to a STM deadlock for some reason?
* Check conflict behavior for both conflicting edits to existing file, * Check conflict behavior for both conflicting edits to existing file,
and conflicting new files. Note need to check both sequences and conflicting new files. Note need to check both sequences
import,export and export,import. import,export and export,import.