@@ -128,6 +128,7 @@ import Control.Distributed.Process.Extras.Internal.Types (whereisRemote)
128import Control.Distributed.Process.ManagedProcess.Client (call, safeCall)
128import Control.Distributed.Process.ManagedProcess.Client (call, safeCall)
129import Control.Distributed.Process (NodeId(..), reconnect)
129import Control.Distributed.Process (NodeId(..), reconnect)
131+import Data.Either (isRight)
131import Data.UUID.V4 (nextRandom)
132import Data.UUID.V4 (nextRandom)
132import Data.Word
133import Data.Word
133import Control.Distributed.Process (ProcessId, Process, receiveWait, send, match)
134import Control.Distributed.Process (ProcessId, Process, receiveWait, send, match)
@@ -580,7 +581,8 @@ autoMergeToHead sessionId (InProcessConnection conf) strat headName' = do
580 Right session -> do
581 Right session -> do
581 case Graph.autoMergeToHead (id1, id2, id3) (Sess.disconnectedTransaction session) headName' strat graph of
582 case Graph.autoMergeToHead (id1, id2, id3) (Sess.disconnectedTransaction session) headName' strat graph of
582 Left err -> pure (Left err)
583 Left err -> pure (Left err)
584+ Right (discon', graph') -> do
583− Right (discon', graph') -> pure (Right (discon', graph', True))
585+ pure (Right (discon', graph', [id1, id2, id3]))
584autoMergeToHead sessionId conn@(RemoteProcessConnection _) strat headName' = remoteCall conn (ExecuteAutoMergeToHead sessionId strat headName')
586autoMergeToHead sessionId conn@(RemoteProcessConnection _) strat headName' = remoteCall conn (ExecuteAutoMergeToHead sessionId strat headName')
586-- | Execute a database context IO-monad-based expression for the given session and connection. `DatabaseContextIOExpr`s modify the DatabaseContext but cannot be purely implemented.
588-- | Execute a database context IO-monad-based expression for the given session and connection. `DatabaseContextIOExpr`s modify the DatabaseContext but cannot be purely implemented.
@@ -645,7 +647,13 @@ executeGraphExpr sessionId (InProcessConnection conf) graphExpr = excEither $ do
645 let discon = Sess.disconnectedTransaction session
647 let discon = Sess.disconnectedTransaction session
646 case evalGraphOp freshId discon updatedGraph graphExpr of
648 case evalGraphOp freshId discon updatedGraph graphExpr of
647 Left err -> pure (Left err)
649 Left err -> pure (Left err)
650+ Right (discon', graph') -> do
651+ --if freshId appears in the graph, then we need to pass it on
652+ let transIds = if isRight (transactionForId freshId graph') then
648− Right (discon', graph') -> pure (Right (discon', graph', isCommit graphExpr))
656+ pure (Right (discon', graph', transIds))
650executeGraphExpr sessionId (InProcessConnection conf) graphExpr = excEither $ do
658executeGraphExpr sessionId (InProcessConnection conf) graphExpr = excEither $ do
651 let strat = ipPersistenceStrategy conf
659 let strat = ipPersistenceStrategy conf
@@ -768,10 +776,10 @@ rollback sessionId conn@(InProcessConnection _) = executeGraphExpr sessionId con
768rollback sessionId conn@(RemoteProcessConnection _) = remoteCall conn (ExecuteGraphExpr sessionId Rollback)
776rollback sessionId conn@(RemoteProcessConnection _) = remoteCall conn (ExecuteGraphExpr sessionId Rollback)
770-- | Write the transaction graph to disk. This function can be used to incrementally write new transactions to disk.
778-- | Write the transaction graph to disk. This function can be used to incrementally write new transactions to disk.
771−processTransactionGraphPersistence :: PersistenceStrategy -> TransactionGraph -> IO ()
779+processTransactionGraphPersistence :: PersistenceStrategy -> [TransactionId] -> TransactionGraph -> IO ()
772−processTransactionGraphPersistence NoPersistence _ = pure ()
780+processTransactionGraphPersistence NoPersistence _ _ = pure ()
773−processTransactionGraphPersistence (MinimalPersistence dbdir) graph = transactionGraphPersist NoDiskSync dbdir graph >> pure ()
781+processTransactionGraphPersistence (MinimalPersistence dbdir) transIds graph = transactionGraphPersist NoDiskSync dbdir transIds graph >> pure ()
774−processTransactionGraphPersistence (CrashSafePersistence dbdir) graph = transactionGraphPersist FsyncDiskSync dbdir graph >> pure ()
782+processTransactionGraphPersistence (CrashSafePersistence dbdir) transIds graph = transactionGraphPersist FsyncDiskSync dbdir transIds graph >> pure ()
776readGraphTransactionIdDigest :: PersistenceStrategy -> IO (LockFileHash)
784readGraphTransactionIdDigest :: PersistenceStrategy -> IO (LockFileHash)
777readGraphTransactionIdDigest NoPersistence = error "attempt to read digest from transaction log without persistence enabled"
785readGraphTransactionIdDigest NoPersistence = error "attempt to read digest from transaction log without persistence enabled"
@@ -947,13 +955,11 @@ disconnectedTransaction_ sessionId (InProcessConnection conf) = do
947 Just (Sess.Session discon _) -> pure discon
955 Just (Sess.Session discon _) -> pure discon
948disconnectedTransaction_ _ _= error "remote connection used"
956disconnectedTransaction_ _ _= error "remote connection used"
950−type ProcessCommit = Bool
952-- wrap a graph evaluation in file locking
958-- wrap a graph evaluation in file locking
953commitLock_ :: SessionId ->
959commitLock_ :: SessionId ->
954 InProcessConnectionConf ->
960 InProcessConnectionConf ->
955 (TransactionGraph ->
961 (TransactionGraph ->
956− STM (Either RelationalError (DisconnectedTransaction, TransactionGraph, ProcessCommit))) ->
962+ STM (Either RelationalError (DisconnectedTransaction, TransactionGraph, [TransactionId]))) ->
957 IO (Either RelationalError ())
963 IO (Either RelationalError ())
958commitLock_ sessionId conf stmBlock = do
964commitLock_ sessionId conf stmBlock = do
959 let sessions = ipSessions conf
965 let sessions = ipSessions conf
@@ -998,25 +1004,25 @@ commitLock_ sessionId conf stmBlock = do
998 eGraph <- stmBlock refreshedGraph
1004 eGraph <- stmBlock refreshedGraph
999 case eGraph of
1005 case eGraph of
1000 Left err -> pure (Left err)
1006 Left err -> pure (Left err)
1001− Right (discon', graph', processCommit) -> do
1007+ Right (discon', graph', transactionIdsToPersist) -> do
1002 writeTVar graphTvar graph'
1008 writeTVar graphTvar graph'
1003 let newSession = Session discon' (Sess.schemaName session)
1009 let newSession = Session discon' (Sess.schemaName session)
1004 STMMap.insert newSession sessionId sessions
1010 STMMap.insert newSession sessionId sessions
1005 case transactionForId (Sess.parentId session) oldGraph of
1011 case transactionForId (Sess.parentId session) oldGraph of
1006 Left err -> pure $ Left err
1012 Left err -> pure $ Left err
1007 Right previousTrans -> do
1013 Right previousTrans -> do
1008− if processCommit then do
1014+ if not (Prelude.null transactionIdsToPersist) then do
1009 (evaldNots, nodes) <- executeCommitExprSTM_ (Trans.concreteDatabaseContext previousTrans) (Sess.concreteDatabaseContext session) clientNodes
1015 (evaldNots, nodes) <- executeCommitExprSTM_ (Trans.concreteDatabaseContext previousTrans) (Sess.concreteDatabaseContext session) clientNodes
1010 nodesToNotify <- toList (STMSet.stream nodes)
1016 nodesToNotify <- toList (STMSet.stream nodes)
1011− pure $ Right (evaldNots, nodesToNotify, graph')
1017+ pure $ Right (evaldNots, nodesToNotify, graph', transactionIdsToPersist)
1012− else pure (Right (M.empty, [], graph'))
1018+ else pure (Right (M.empty, [], graph', []))
1014 --handle notification firing
1020 --handle notification firing
1015 case manip of
1021 case manip of
1016 Left err -> pure (Left err)
1022 Left err -> pure (Left err)
1017− Right (notsToFire, nodesToNotify, newGraph) -> do
1023+ Right (notsToFire, nodesToNotify, newGraph, transactionIdsToPersist) -> do
1018 --update filesystem database, if necessary
1024 --update filesystem database, if necessary
1019− processTransactionGraphPersistence strat newGraph
1025+ processTransactionGraphPersistence strat transactionIdsToPersist newGraph
1020 sendNotifications nodesToNotify (ipLocalNode conf) notsToFire
1026 sendNotifications nodesToNotify (ipLocalNode conf) notsToFire
1021 pure (Right ())
1027 pure (Right ())