@@ -20,14 +20,18 @@ module ProjectM36.Client
2020 processPersistence,
2121 transactionGraphAsRelation,
2222 headName,
23+ remoteDBLookupName,
24+ defaultServerPort,
2325 headTransactionUUID,
2426 PersistenceStrategy(..),
2527 RelationalExpr(..),
2628 DatabaseExpr(..),
2729 Attribute(..),
2830 attributesFromList,
31+ createNodeId,
2932 TransactionGraphOperator(..),
3033 Atomable,
34+ NodeId(..),
3135 Atom(..),
3236 AtomType(..)) where
3337import ProjectM36.Base hiding (inclusionDependencies) --defined in this module as well
@@ -43,7 +47,7 @@ import ProjectM36.TransactionGraph.Persist
4347import ProjectM36.Attribute
4448import ProjectM36.Persist (DiskSync(..))
4549import ProjectM36.Daemon.RemoteCallTypes (RemoteExecution(..))
46−import Network.Transport.TCP (createTransport, defaultTCPParameters)
50+import Network.Transport.TCP (createTransport, defaultTCPParameters, encodeEndPointAddress)
4751import Control.Distributed.Process.Node (newLocalNode, initRemoteTable, runProcess, LocalNode)
4852import Control.Distributed.Process.Extras.Internal.Types (whereisRemote)
4953import Control.Distributed.Process.ManagedProcess.Client (call)
@@ -53,12 +57,12 @@ import Data.UUID (UUID)
5357import Data.UUID.V4 (nextRandom)
5458import Control.Concurrent.STM
5559import Data.Word
56−import Control.Distributed.Process (ProcessId)
60+import Control.Distributed.Process (ProcessId, Process)
5761import Control.Exception (IOException)
5862import Control.Concurrent.MVar
5963import qualified Data.Map as M
6064
61−type Hostname = StringType
65+type Hostname = String
6266
6367type Port = Word16
6468
@@ -67,8 +71,14 @@ type DatabaseName = String
6771data ConnectionInfo = InProcessConnectionInfo PersistenceStrategy |
6872 RemoteProcessConnectionInfo DatabaseName NodeId
6973
74+createNodeId :: Hostname -> Port -> NodeId
75+createNodeId host port = NodeId $ encodeEndPointAddress host (show port) 0
76+
77+defaultServerPort :: Port
78+defaultServerPort = 6543
79+
7080data Connection = InProcessConnection PersistenceStrategy (TVar (DisconnectedTransaction, TransactionGraph)) |
71− RemoteProcessConnection ProcessId
81+ RemoteProcessConnection LocalNode ProcessId -- perhaps should reference the local node as well
7282
7383data ConnectionError = SetupDatabaseDirectoryError PersistenceError |
7484 IOExceptionError IOException |
@@ -105,11 +115,13 @@ connectProjectM36 (InProcessConnectionInfo strat) = do
105115connectProjectM36 (RemoteProcessConnectionInfo databaseName serverNodeId) = do
106116 connStatus <- newEmptyMVar
107117 eLocalNode <- commonLocalNode
118+ let dbName = remoteDBLookupName databaseName
119+ putStrLn $ show serverNodeId ++ " " ++ dbName
108120 case eLocalNode of
109121 Left err -> pure (Left err)
110122 Right localNode -> do
111123 runProcess localNode $ do
112− mServerProcessId <- whereisRemote serverNodeId (remoteDBLookupName databaseName)
124+ mServerProcessId <- whereisRemote serverNodeId dbName
113125 case mServerProcessId of
114126 Nothing -> liftIO $ putMVar connStatus $ Left (NoSuchDatabaseByNameError databaseName)
115127 Just serverProcessId -> do
@@ -117,7 +129,7 @@ connectProjectM36 (RemoteProcessConnectionInfo databaseName serverNodeId) = do
117129 if not loginConfirmation then
118130 liftIO $ putMVar connStatus (Left LoginError)
119131 else do
120− liftIO $ putMVar connStatus (Right $ RemoteProcessConnection serverProcessId)
132+ liftIO $ putMVar connStatus (Right $ RemoteProcessConnection localNode serverProcessId)
121133 status <- takeMVar connStatus
122134 pure status
123135
@@ -141,19 +153,25 @@ connectPersistentProjectM36 strat sync dbdir freshDiscon freshGraph = do
141153
142154close :: Connection -> IO ()
143155close (InProcessConnection _ _) = pure ()
144−close (RemoteProcessConnection serverProcessId) = do
145− eLocalNode <- commonLocalNode
146− case eLocalNode of
147− Left _ -> pure () --consider returning an error or exception
148− Right localNode -> do
149− runProcess localNode $ do
150− call serverProcessId Logout
151− pure ()
156+close (RemoteProcessConnection localNode serverProcessId) = do
157+ runProcessResult localNode $ do
158+ call serverProcessId Logout
159+
160+runProcessResult :: LocalNode -> Process a -> IO a
161+runProcessResult localNode proc = do
162+ ret <- newEmptyMVar
163+ runProcess localNode $ do
164+ val <- proc
165+ liftIO $ putMVar ret val
166+ takeMVar ret
152167
153168executeRelationalExpr :: Connection -> RelationalExpr -> IO (Either RelationalError Relation)
154169executeRelationalExpr (InProcessConnection _ tvar) expr = atomically $ do
155170 ((DisconnectedTransaction _ context), _) <- readTVar tvar
156171 return $ evalState (RE.evalRelationalExpr expr) context
172+executeRelationalExpr (RemoteProcessConnection localNode serverProcessId) relExpr = do
173+ runProcessResult localNode $ do
174+ call serverProcessId (ExecuteRelationalExpr relExpr)
157175
158176executeDatabaseContextExpr :: Connection -> DatabaseExpr -> IO (Maybe RelationalError)
159177executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
@@ -164,6 +182,8 @@ executeDatabaseContextExpr (InProcessConnection _ tvar) expr = atomically $ do
164182 let newDiscon = DisconnectedTransaction parentUUID context'
165183 writeTVar tvar (newDiscon, graph)
166184 return Nothing
185+executeDatabaseContextExpr (RemoteProcessConnection localNode serverProcessId) dbExpr = do
186+ runProcessResult localNode $ call serverProcessId (ExecuteDatabaseContextExpr dbExpr)
167187
168188executeGraphExpr :: Connection -> TransactionGraphOperator -> IO (Maybe RelationalError)
169189executeGraphExpr (InProcessConnection strat tvar) graphExpr = do
@@ -242,6 +262,10 @@ headName (InProcessConnection _ tvar) = do
242262 pure $ case transactionForUUID parentUUID graph of
243263 Left _ -> Nothing
244264 Right parentTrans -> headNameForTransaction parentTrans graph
245−
265+headName (RemoteProcessConnection localNode serverProcessId) = do
266+ runProcessResult localNode $ do
267+ ret <- call serverProcessId ExecuteHeadName
268+ pure ret
269+
246270
247271