summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2017-09-18 19:42:20 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2017-09-18 19:42:20 -0400
commit4b15fe18fb868d138d1bdfdf3d71b7a11de7a282 (patch)
treee47cb52c229e920c0bcad2d9a9dd76f3a82aa36c
parent15ea6c9f3eb1bc741d79f898d1ec45af74dcbb23 (diff)
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.
-rw-r--r--Database/Handle.hs26
-rw-r--r--doc/todo/export.mdwn3
2 files changed, 18 insertions, 11 deletions
diff --git a/Database/Handle.hs b/Database/Handle.hs
index f5a0a5dda..5670acb99 100644
--- a/Database/Handle.hs
+++ b/Database/Handle.hs
@@ -142,11 +142,15 @@ data Job
| CloseJob
workerThread :: T.Text -> TableName -> MVar Job -> IO ()
-workerThread db tablename jobs =
- catchNonAsync (runSqliteRobustly tablename db loop) showerr
+workerThread db tablename jobs = go
where
- showerr e = hPutStrLn stderr $
- "sqlite worker thread crashed: " ++ show e
+ go = do
+ v <- tryNonAsync (runSqliteRobustly tablename db loop)
+ case v of
+ Left e -> hPutStrLn stderr $
+ "sqlite worker thread crashed: " ++ show e
+ Right True -> go
+ Right False -> return ()
getjob :: IO (Either BlockedIndefinitelyOnMVar Job)
getjob = try $ takeMVar jobs
@@ -157,15 +161,21 @@ workerThread db tablename jobs =
-- Exception is thrown when the MVar is garbage
-- collected, which means the whole DbHandle
-- is not used any longer. Shutdown cleanly.
- Left BlockedIndefinitelyOnMVar -> return ()
- Right CloseJob -> return ()
+ Left BlockedIndefinitelyOnMVar -> return False
+ Right CloseJob -> return False
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
-- since sqlite only supports a single writer at a
-- time, and it may crash the database connection
-- 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.
runSqliteRobustly :: TableName -> T.Text -> (SqlPersistM a) -> IO a
diff --git a/doc/todo/export.mdwn b/doc/todo/export.mdwn
index 6c6789a29..4c707a779 100644
--- a/doc/todo/export.mdwn
+++ b/doc/todo/export.mdwn
@@ -17,9 +17,6 @@ there need to be a new interface in supported remotes?
Work is in progress. Todo list:
-* bug: export db update does not reash disk after Remote.Helper.Export calls
- updateExportTree.
-
* tracking exports
* Support configuring export in the assistant