avoid using a second db connection for writes
This is a potentially breaking change in a very delicate area. However,
examining the code path for writes, I don't see any benefit to opening a
second db connection for them. If the write throws an exception,
commitDb will retry it with a new db connection.
A potential benefit to not opening a second db connection, beyond using
less resources, is it just might avoid problems in WSL with sqlite that
I have hypothesized are caused by multiple db connections.
Commit 5f9eff3f32
explains why it needs to
shut down the db connection to force the database to be updated on disk:
When closeDb does not get called, garbage collection of DbHandle may not
give the workterThread time to cleanly shut down before git-annex exits,
resulting in a recently written change not reaching disk.
This commit is contained in:
parent
f5b642318d
commit
d0ef8303cf
1 changed files with 6 additions and 12 deletions
|
@ -100,13 +100,13 @@ commitDb h wa = robustly Nothing 100 (commitDb' h wa)
|
|||
commitDb' :: DbHandle -> SqlPersistM () -> IO (Either SomeException ())
|
||||
commitDb' (DbHandle _ jobs) a = do
|
||||
res <- newEmptyMVar
|
||||
putMVar jobs $ ChangeJob $ \runner ->
|
||||
liftIO $ putMVar res =<< tryNonAsync (runner a)
|
||||
putMVar jobs $ ChangeJob $
|
||||
liftIO . putMVar res =<< tryNonAsync a
|
||||
takeMVar res
|
||||
|
||||
data Job
|
||||
= QueryJob (SqlPersistM ())
|
||||
| ChangeJob ((SqlPersistM () -> IO ()) -> IO ())
|
||||
| ChangeJob (SqlPersistM ())
|
||||
| CloseJob
|
||||
|
||||
workerThread :: T.Text -> TableName -> MVar Job -> IO ()
|
||||
|
@ -128,16 +128,10 @@ workerThread db tablename jobs = newconn
|
|||
Left BlockedIndefinitelyOnMVar -> return (return ())
|
||||
Right CloseJob -> return (return ())
|
||||
Right (QueryJob a) -> a >> loop
|
||||
-- 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 (ChangeJob a) -> do
|
||||
liftIO (a (runSqliteRobustly tablename db))
|
||||
-- Exit this sqlite connection so the
|
||||
-- change that was just written, using
|
||||
-- a different db handle, is immediately
|
||||
-- visible to queries.
|
||||
a
|
||||
-- Exit the sqlite connection so the
|
||||
-- database gets updated on disk.
|
||||
return newconn
|
||||
|
||||
getjob :: IO (Either BlockedIndefinitelyOnMVar Job)
|
||||
|
|
Loading…
Reference in a new issue