@@ -16,7 +16,6 @@ module ProjectM36.Client
16 typeForRelationalExpr,
16 typeForRelationalExpr,
17 inclusionDependencies,
17 inclusionDependencies,
18 planForDatabaseContextExpr,
18 planForDatabaseContextExpr,
19− attributesForRelationalExpr,
20 processPersistence,
19 processPersistence,
21 transactionGraphAsRelation,
20 transactionGraphAsRelation,
@@ -37,7 +36,6 @@ module ProjectM36.Client
37import ProjectM36.Base hiding (inclusionDependencies) --defined in this module as well
36import ProjectM36.Base hiding (inclusionDependencies) --defined in this module as well
38import qualified ProjectM36.Base as B
37import qualified ProjectM36.Base as B
39import ProjectM36.Error
38import ProjectM36.Error
40−import ProjectM36.Relation
41import ProjectM36.StaticOptimizer
39import ProjectM36.StaticOptimizer
42import Control.Monad.State
40import Control.Monad.State
43import ProjectM36.Transaction
41import ProjectM36.Transaction
@@ -50,17 +48,19 @@ import ProjectM36.Daemon.RemoteCallTypes (RemoteExecution(..))
50import Network.Transport.TCP (createTransport, defaultTCPParameters, encodeEndPointAddress)
48import Network.Transport.TCP (createTransport, defaultTCPParameters, encodeEndPointAddress)
51import Control.Distributed.Process.Node (newLocalNode, initRemoteTable, runProcess, LocalNode)
49import Control.Distributed.Process.Node (newLocalNode, initRemoteTable, runProcess, LocalNode)
52import Control.Distributed.Process.Extras.Internal.Types (whereisRemote)
50import Control.Distributed.Process.Extras.Internal.Types (whereisRemote)
53−import Control.Distributed.Process.ManagedProcess.Client (call)
51+import Control.Distributed.Process.ManagedProcess.Client (call, safeCall)
54import Control.Distributed.Process (NodeId(..))
52import Control.Distributed.Process (NodeId(..))
56import Data.UUID (UUID)
54import Data.UUID (UUID)
57import Data.UUID.V4 (nextRandom)
55import Data.UUID.V4 (nextRandom)
58import Control.Concurrent.STM
56import Control.Concurrent.STM
59import Data.Word
57import Data.Word
60−import Control.Distributed.Process (ProcessId, Process)
58+import Control.Distributed.Process (ProcessId, Process, getSelfPid)
61import Control.Exception (IOException)
59import Control.Exception (IOException)
62import Control.Concurrent.MVar
60import Control.Concurrent.MVar
63import qualified Data.Map as M
61import qualified Data.Map as M
62+import Control.Distributed.Process.Serializable (Serializable)
63+--import Control.Distributed.Process.Debug
65type Hostname = String
65type Hostname = String
@@ -165,13 +165,21 @@ runProcessResult localNode proc = do
165 liftIO $ putMVar ret val
165 liftIO $ putMVar ret val
166 takeMVar ret
166 takeMVar ret
168+remoteCall :: (Serializable a, Serializable b) => Connection -> a -> IO b
169+remoteCall (InProcessConnection _ _) _ = error "remoteCall called on local connection"
170+remoteCall (RemoteProcessConnection localNode serverProcessId) arg = runProcessResult localNode $ do
172+ liftIO $ putStrLn (show serverProcessId)
173+ ret <- safeCall serverProcessId arg
175+ Left err -> error (show err)
176+ Right ret' -> pure ret'
168executeRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
178executeRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
169executeRelationalExpr (InProcessConnection _ tvar) expr = atomically $ do
179executeRelationalExpr (InProcessConnection _ tvar) expr = atomically $ do
170 ((DisconnectedTransaction _ context), _) <- readTVar tvar
180 ((DisconnectedTransaction _ context), _) <- readTVar tvar
171 return $ evalState (RE.evalRelationalExpr expr) context
181 return $ evalState (RE.evalRelationalExpr expr) context
172−executeRelationalExpr (RemoteProcessConnection localNode serverProcessId) relExpr = do
182+executeRelationalExpr conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteRelationalExpr relExpr)
173− runProcessResult localNode $ do
174− call serverProcessId (ExecuteRelationalExpr relExpr)
176executeDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Maybe RelationalError)
184executeDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Maybe RelationalError)
177executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
185executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
@@ -182,8 +190,7 @@ executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
182 let newDiscon = DisconnectedTransaction parentUUID context'
190 let newDiscon = DisconnectedTransaction parentUUID context'
183 writeTVar tvar (newDiscon, graph)
191 writeTVar tvar (newDiscon, graph)
184 return Nothing
192 return Nothing
185−executeDatabaseContextExpr (RemoteProcessConnection localNode serverProcessId) dbExpr = do
193+executeDatabaseContextExpr conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (ExecuteDatabaseContextExpr dbExpr)
186− runProcessResult localNode $ call serverProcessId (ExecuteDatabaseContextExpr dbExpr)
188executeGraphExpr :: Connection -> TransactionGraphOperator -> IO (Maybe RelationalError)
195executeGraphExpr :: Connection -> TransactionGraphOperator -> IO (Maybe RelationalError)
189executeGraphExpr (InProcessConnection strat tvar) graphExpr = do
196executeGraphExpr (InProcessConnection strat tvar) graphExpr = do
@@ -202,15 +209,15 @@ executeGraphExpr (InProcessConnection strat tvar) graphExpr = do
202 --this should really grab a lock at the beginning of the method to be threadsafe
209 --this should really grab a lock at the beginning of the method to be threadsafe
203 processPersistence strat newGraph
210 processPersistence strat newGraph
204 return Nothing
211 return Nothing
205−executeGraphExpr (RemoteProcessConnection localNode serverProcessId) graphExpr = do
212+executeGraphExpr conn@(RemoteProcessConnection _ _) graphExpr = remoteCall conn (ExecuteGraphExpr graphExpr)
206− runProcessResult localNode $ do
207− call serverProcessId (ExecuteGraphExpr graphExpr)
209commit :: Connection -> IO (Maybe RelationalError)
214commit :: Connection -> IO (Maybe RelationalError)
210−commit conn = executeGraphExpr conn Commit
215+commit conn@(InProcessConnection _ _) = executeGraphExpr conn Commit
216+commit conn@(RemoteProcessConnection _ _) = remoteCall conn (ExecuteGraphExpr Commit)
212rollback :: Connection -> IO (Maybe RelationalError)
218rollback :: Connection -> IO (Maybe RelationalError)
213−rollback conn = executeGraphExpr conn Rollback
219+rollback conn@(InProcessConnection _ _) = executeGraphExpr conn Rollback
220+rollback conn@(RemoteProcessConnection _ _) = remoteCall conn (ExecuteGraphExpr Rollback)
215processPersistence :: PersistenceStrategy -> TransactionGraph -> IO ()
222processPersistence :: PersistenceStrategy -> TransactionGraph -> IO ()
216processPersistence NoPersistence _ = return ()
223processPersistence NoPersistence _ = return ()
@@ -219,43 +226,43 @@ processPersistence (CrashSafePersistence dbdir) graph = transactionGraphPersist
220typeForRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
227typeForRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
221typeForRelationalExpr conn@(InProcessConnection _ _) relExpr = atomically $ typeForRelationalExprSTM conn relExpr
228typeForRelationalExpr conn@(InProcessConnection _ _) relExpr = atomically $ typeForRelationalExprSTM conn relExpr
229+typeForRelationalExpr conn@(RemoteProcessConnection _ _) relExpr = remoteCall conn (ExecuteTypeForRelationalExpr relExpr)
223typeForRelationalExprSTM :: Connection -> RelationalExpr -> STM (Either RelationalError Relation)
231typeForRelationalExprSTM :: Connection -> RelationalExpr -> STM (Either RelationalError Relation)
224typeForRelationalExprSTM (InProcessConnection _ tvar) relExpr = do
232typeForRelationalExprSTM (InProcessConnection _ tvar) relExpr = do
225 (DisconnectedTransaction _ context, _) <- readTVar tvar
233 (DisconnectedTransaction _ context, _) <- readTVar tvar
226 pure $ evalState (RE.typeForRelationalExpr relExpr) context
234 pure $ evalState (RE.typeForRelationalExpr relExpr) context
235+typeForRelationalExprSTM _ _ = error "typeForRelationalExprSTM called on non-local connection"
228inclusionDependencies :: Connection -> IO (M.Map IncDepName InclusionDependency)
237inclusionDependencies :: Connection -> IO (M.Map IncDepName InclusionDependency)
229inclusionDependencies (InProcessConnection _ tvar) = do
238inclusionDependencies (InProcessConnection _ tvar) = do
230 atomically $ do
239 atomically $ do
231 ((DisconnectedTransaction _ context), _) <- readTVar tvar
240 ((DisconnectedTransaction _ context), _) <- readTVar tvar
232 pure (B.inclusionDependencies context)
241 pure (B.inclusionDependencies context)
242+inclusionDependencies conn@(RemoteProcessConnection _ _) = remoteCall conn RetrieveInclusionDependencies
234planForDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Either RelationalError DatabaseExpr)
245planForDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Either RelationalError DatabaseExpr)
235planForDatabaseContextExpr (InProcessConnection _ tvar) dbExpr = do
246planForDatabaseContextExpr (InProcessConnection _ tvar) dbExpr = do
236 atomically $ do
247 atomically $ do
237 ((DisconnectedTransaction _ context), _) <- readTVar tvar
248 ((DisconnectedTransaction _ context), _) <- readTVar tvar
238 pure $ evalState (applyStaticDatabaseOptimization dbExpr) context
249 pure $ evalState (applyStaticDatabaseOptimization dbExpr) context
250+planForDatabaseContextExpr conn@(RemoteProcessConnection _ _) dbExpr = remoteCall conn (RetrievePlanForDatabaseContextExpr dbExpr)
240transactionGraphAsRelation :: Connection -> IO (Either RelationalError Relation)
252transactionGraphAsRelation :: Connection -> IO (Either RelationalError Relation)
241transactionGraphAsRelation (InProcessConnection _ tvar) = do
253transactionGraphAsRelation (InProcessConnection _ tvar) = do
242 atomically $ do
254 atomically $ do
243 (discon, graph) <- readTVar tvar
255 (discon, graph) <- readTVar tvar
244 pure $ graphAsRelation discon graph
256 pure $ graphAsRelation discon graph
245−
257+transactionGraphAsRelation conn@(RemoteProcessConnection _ _) = remoteCall conn RetrieveTransactionGraph
246−attributesForRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Attributes)
258+
247−attributesForRelationalExpr conn relExpr = atomically $ do
248− eRelType <- typeForRelationalExprSTM conn relExpr
249− pure $ case eRelType of
250− Left err -> Left err
251− Right relType -> Right $ attributes relType
253-- | Returns the UUID for the connection's disconnected transaction committed parent transaction.
259-- | Returns the UUID for the connection's disconnected transaction committed parent transaction.
254headTransactionUUID :: Connection -> IO (UUID)
260headTransactionUUID :: Connection -> IO (UUID)
255headTransactionUUID (InProcessConnection _ tvar) = do
261headTransactionUUID (InProcessConnection _ tvar) = do
256 atomically $ do
262 atomically $ do
257 (DisconnectedTransaction parentUUID _, _) <- readTVar tvar
263 (DisconnectedTransaction parentUUID _, _) <- readTVar tvar
258 pure parentUUID
264 pure parentUUID
265+headTransactionUUID conn@(RemoteProcessConnection _ _) = remoteCall conn RetrieveHeadTransactionUUID
260-- | Returns Just the name of the head of the current disconnected transaction or Nothing.
267-- | Returns Just the name of the head of the current disconnected transaction or Nothing.
261headName :: Connection -> IO (Maybe HeadName)
268headName :: Connection -> IO (Maybe HeadName)