fix bug that prevented db being written to disk in SingleWriter mode

The bug occurred when closeDb was not called, and garbage collection of
the DbHandle didn't give the workerThread time to shut down. Fixed by
exiting the runSqlite action when a commit is made.

(MultiWriter mode already forked off a runSqlite action, so avoided the
problem.)

This commit was sponsored by Brock Spratlen on Patreon.
This commit is contained in:
Joey Hess 2017-09-18 19:42:20 -04:00
parent c35fd698aa
commit 5f9eff3f32
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 18 additions and 11 deletions

View file

@ -142,11 +142,15 @@ data Job
| CloseJob | CloseJob
workerThread :: T.Text -> TableName -> MVar Job -> IO () workerThread :: T.Text -> TableName -> MVar Job -> IO ()
workerThread db tablename jobs = workerThread db tablename jobs = go
catchNonAsync (runSqliteRobustly tablename db loop) showerr
where where
showerr e = hPutStrLn stderr $ go = do
v <- tryNonAsync (runSqliteRobustly tablename db loop)
case v of
Left e -> hPutStrLn stderr $
"sqlite worker thread crashed: " ++ show e "sqlite worker thread crashed: " ++ show e
Right True -> go
Right False -> return ()
getjob :: IO (Either BlockedIndefinitelyOnMVar Job) getjob :: IO (Either BlockedIndefinitelyOnMVar Job)
getjob = try $ takeMVar jobs getjob = try $ takeMVar jobs
@ -157,15 +161,21 @@ workerThread db tablename jobs =
-- Exception is thrown when the MVar is garbage -- Exception is thrown when the MVar is garbage
-- collected, which means the whole DbHandle -- collected, which means the whole DbHandle
-- is not used any longer. Shutdown cleanly. -- is not used any longer. Shutdown cleanly.
Left BlockedIndefinitelyOnMVar -> return () Left BlockedIndefinitelyOnMVar -> return False
Right CloseJob -> return () Right CloseJob -> return False
Right (QueryJob a) -> a >> loop Right (QueryJob a) -> a >> loop
Right (ChangeJob a) -> a >> loop Right (ChangeJob a) -> do
a
-- Exit this sqlite transaction so the
-- database gets updated on disk.
return True
-- Change is run in a separate database connection -- Change is run in a separate database connection
-- since sqlite only supports a single writer at a -- since sqlite only supports a single writer at a
-- time, and it may crash the database connection -- time, and it may crash the database connection
-- that the write is made to. -- that the write is made to.
Right (RobustChangeJob a) -> liftIO (a (runSqliteRobustly tablename db)) >> loop Right (RobustChangeJob a) -> do
liftIO (a (runSqliteRobustly tablename db))
loop
-- like runSqlite, but calls settle on the raw sql Connection. -- like runSqlite, but calls settle on the raw sql Connection.
runSqliteRobustly :: TableName -> T.Text -> (SqlPersistM a) -> IO a runSqliteRobustly :: TableName -> T.Text -> (SqlPersistM a) -> IO a

View file

@ -17,9 +17,6 @@ there need to be a new interface in supported remotes?
Work is in progress. Todo list: Work is in progress. Todo list:
* bug: export db update does not reash disk after Remote.Helper.Export calls
updateExportTree.
* tracking exports * tracking exports
* Support configuring export in the assistant * Support configuring export in the assistant