on master help sign in
more serializer changes
2af128dAgentM
project-m36.cabal+1−1
@@ -34,7 +34,7 @@ Flag haskell-scripting
34 Default: True
34 Default: True
35
35
36Library
36Library
37− Build-Depends: base>=4.8 && < 4.15, ghc-paths, mtl, containers, unordered-containers, hashable, haskeline, directory, MonadRandom, random-shuffle, uuid >= 1.3.12, cassava >= 0.4.5.1 && < 0.6, text, bytestring, deepseq, deepseq-generics, vector, parallel, monad-parallel, exceptions, transformers, gnuplot, binary, filepath, zlib, directory, vector-binary-instances, temporary, stm, time, hashable-time, old-locale, rset, attoparsec, either, base64-bytestring, data-interval, extended-reals, network-transport, aeson >= 1.1, path-pieces, conduit, resourcet, http-api-data, semigroups, QuickCheck, quickcheck-instances, distributed-process-client-server >= 0.2.3, distributed-process >= 0.7.4, distributed-process-extras >= 0.3.2, distributed-process-async >= 0.2.4.1, network-transport-tcp >= 0.6.0, network-transport, list-t, stm-containers >= 0.2.15, foldl, optparse-applicative, Glob, cryptohash-sha256, text-manipulate >= 0.2.0.1 && < 0.3, winery
37+ Build-Depends: base>=4.8 && < 4.15, ghc-paths, mtl, containers, unordered-containers, hashable, haskeline, directory, MonadRandom, random-shuffle, uuid >= 1.3.12, cassava >= 0.4.5.1 && < 0.6, text, bytestring, deepseq, deepseq-generics, vector, parallel, monad-parallel, exceptions, transformers, gnuplot, binary, filepath, zlib, directory, vector-binary-instances, temporary, stm, time, hashable-time, old-locale, rset, attoparsec, either, base64-bytestring, data-interval, extended-reals, network-transport, aeson >= 1.1, path-pieces, conduit, resourcet, http-api-data, semigroups, QuickCheck, quickcheck-instances, distributed-process-client-server >= 0.2.3, distributed-process >= 0.7.4, distributed-process-extras >= 0.3.2, distributed-process-async >= 0.2.4.1, network-transport-tcp >= 0.6.0, network-transport, list-t, stm-containers >= 0.2.15, foldl, optparse-applicative, Glob, cryptohash-sha256, text-manipulate >= 0.2.0.1 && < 0.3, winery, curryer, network
38 if flag(haskell-scripting)
38 if flag(haskell-scripting)
39 Build-Depends: ghc >= 8.2 && < 8.11
39 Build-Depends: ghc >= 8.2 && < 8.11
40 CPP-Options: -DPM36_HASKELL_SCRIPTING
40 CPP-Options: -DPM36_HASKELL_SCRIPTING
src/lib/ProjectM36/Client.hs+84−142
@@ -1,4 +1,4 @@
1−{-# LANGUAGE DeriveAnyClass, DeriveGeneric, ScopedTypeVariables, MonoLocalBinds #-}
1+{-# LANGUAGE DeriveAnyClass, DeriveGeneric, ScopedTypeVariables, MonoLocalBinds, DerivingVia, GeneralizedNewtypeDeriving #-}
2{-|
2{-|
3Module: ProjectM36.Client
3Module: ProjectM36.Client
4
4
@@ -53,11 +53,9 @@ module ProjectM36.Client
53 Attribute(..),
53 Attribute(..),
54 MergeStrategy(..),
54 MergeStrategy(..),
55 attributesFromList,
55 attributesFromList,
56− createNodeId,
57 createSessionAtCommit,
56 createSessionAtCommit,
58 createSessionAtHead,
57 createSessionAtHead,
59 closeSession,
58 closeSession,
60− addClientNode,
61 callTestTimeout_,
59 callTestTimeout_,
62 RelationCardinality(..),
60 RelationCardinality(..),
63 TransactionGraphOperator(..),
61 TransactionGraphOperator(..),
@@ -67,7 +65,6 @@ module ProjectM36.Client
67 TransGraphRelationalExpr,
65 TransGraphRelationalExpr,
68 TransactionIdLookup(..),
66 TransactionIdLookup(..),
69 TransactionIdHeadBacktrack(..),
67 TransactionIdHeadBacktrack(..),
70− NodeId(..),
71 Atom(..),
68 Atom(..),
72 Session,
69 Session,
73 SessionId,
70 SessionId,
@@ -141,6 +138,7 @@ import Data.UUID.V4 (nextRandom)
141import Data.Word
138import Data.Word
142import Control.Exception (IOException, handle, AsyncException, throwIO, fromException, Exception)
139import Control.Exception (IOException, handle, AsyncException, throwIO, fromException, Exception)
143import Control.Concurrent.MVar
140import Control.Concurrent.MVar
141+import Codec.Winery hiding (Schema)
144import qualified Data.Map as M
142import qualified Data.Map as M
145#if MIN_VERSION_stm_containers(1,0,0)
143#if MIN_VERSION_stm_containers(1,0,0)
146import qualified StmContainers.Map as StmMap
144import qualified StmContainers.Map as StmMap
@@ -152,12 +150,15 @@ import qualified STMContainers.Set as StmSet
152import qualified ProjectM36.Session as Sess
150import qualified ProjectM36.Session as Sess
153import ProjectM36.Session
151import ProjectM36.Session
154import ProjectM36.Sessions
152import ProjectM36.Sessions
155−import Data.Binary (Binary)
156import GHC.Generics (Generic)
153import GHC.Generics (Generic)
157import Control.DeepSeq (force)
154import Control.DeepSeq (force)
158import System.IO
155import System.IO
159import Data.Time.Clock
156import Data.Time.Clock
160import Data.Typeable
157import Data.Typeable
158+import qualified Network.RPC.Curryer.Client as RPC
159+import qualified Network.RPC.Curryer.Server as RPC
160+import Network.Socket (PortNumber, AddrInfo(..), getAddrInfo, defaultHints, AddrInfoFlag(..), SocketType(..), ServiceName, hostAddressToTuple, SockAddr(..))
161+import Data.Word
161
162
162type Hostname = String
163type Hostname = String
163
164
@@ -185,14 +186,15 @@ data RequestTimeoutException = RequestTimeoutException
185instance Exception RequestTimeoutException
186instance Exception RequestTimeoutException
186
187
187-- | Construct a 'ConnectionInfo' to describe how to make the 'Connection'. The database can be run within the current process or running remotely via distributed-process.
188-- | Construct a 'ConnectionInfo' to describe how to make the 'Connection'. The database can be run within the current process or running remotely via distributed-process.
188−data ConnectionInfo = InProcessConnectionInfo PersistenceStrategy NotificationCallback [GhcPkgPath]|
189+data ConnectionInfo = InProcessConnectionInfo PersistenceStrategy NotificationCallback [GhcPkgPath] |
189− RemoteProcessConnectionInfo DatabaseName NodeId NotificationCallback
190+ RemoteConnectionInfo DatabaseName Hostname ServiceName NotificationCallback
190
191
191type EvaluatedNotifications = M.Map NotificationName EvaluatedNotification
192type EvaluatedNotifications = M.Map NotificationName EvaluatedNotification
192
193
193-- | Used for callbacks from the server when monitored changes have been made.
194-- | Used for callbacks from the server when monitored changes have been made.
194newtype NotificationMessage = NotificationMessage EvaluatedNotifications
195newtype NotificationMessage = NotificationMessage EvaluatedNotifications
195− deriving (Binary, Eq, Show, Generic)
196+ deriving (Eq, Show, Generic)
197+ deriving Serialise via WineryVariant NotificationMessage
196
198
197-- | When a notification is fired, the 'reportOldExpr' is evaluated in the commit's pre-change context while the 'reportNewExpr' is evaluated in the post-change context and they are returned along with the original notification.
199-- | When a notification is fired, the 'reportOldExpr' is evaluated in the commit's pre-change context while the 'reportNewExpr' is evaluated in the post-change context and they are returned along with the original notification.
198data EvaluatedNotification = EvaluatedNotification {
200data EvaluatedNotification = EvaluatedNotification {
@@ -200,16 +202,13 @@ data EvaluatedNotification = EvaluatedNotification {
200 reportOldRelation :: Either RelationalError Relation,
202 reportOldRelation :: Either RelationalError Relation,
201 reportNewRelation :: Either RelationalError Relation
203 reportNewRelation :: Either RelationalError Relation
202 }
204 }
203− deriving(Binary, Eq, Show, Generic)
205+ deriving (Eq, Show, Generic)
206+ deriving Serialise via WineryRecord EvaluatedNotification
204
207
205
208
206−-- | Create a 'NodeId' for use in connecting to a remote server using distributed-process.
207−createNodeId :: Hostname -> Port -> NodeId
208−createNodeId host port = NodeId $ encodeEndPointAddress host (show port) 1
209−
210-- | Use this for connecting to remote servers on the default port.
209-- | Use this for connecting to remote servers on the default port.
211−defaultServerPort :: Port
210+defaultServerPort :: ServiceName
212−defaultServerPort = 6543
211+defaultServerPort = "6543"
213
212
214-- | Use this for connecting to remote servers with the default database name.
213-- | Use this for connecting to remote servers with the default database name.
215defaultDatabaseName :: DatabaseName
214defaultDatabaseName :: DatabaseName
@@ -221,10 +220,14 @@ defaultHeadName = "master"
221
220
222-- | Create a connection configuration which connects to the localhost on the default server port and default server database name. The configured notification callback is set to ignore all events.
221-- | Create a connection configuration which connects to the localhost on the default server port and default server database name. The configured notification callback is set to ignore all events.
223defaultRemoteConnectionInfo :: ConnectionInfo
222defaultRemoteConnectionInfo :: ConnectionInfo
223+defaultRemoteConnectionInfo =
224−defaultRemoteConnectionInfo = RemoteProcessConnectionInfo defaultDatabaseName (createNodeId "127.0.0.1" defaultServerPort) emptyNotificationCallback
224+ RemoteConnectionInfo defaultDatabaseName defaultServerHostname defaultServerPort emptyNotificationCallback
225+
226+defaultServerHostname :: Hostname
227+defaultServerHostname = "localhost"
225
228
226-- | The 'Connection' represents either local or remote access to a database. All operations flow through the connection.
229-- | The 'Connection' represents either local or remote access to a database. All operations flow through the connection.
227−type ClientNodes = StmSet.Set ProcessId
230+type ClientNodes = StmSet.Set RPCConnection -- not correct- we need an object to represent all client connection on the server side - this is missing in Curryer
228
231
229-- internal structure specific to in-process connections
232-- internal structure specific to in-process connections
230data InProcessConnectionConf = InProcessConnectionConf {
233data InProcessConnectionConf = InProcessConnectionConf {
@@ -233,19 +236,15 @@ data InProcessConnectionConf = InProcessConnectionConf {
233 ipSessions :: Sessions,
236 ipSessions :: Sessions,
234 ipTransactionGraph :: TVar TransactionGraph,
237 ipTransactionGraph :: TVar TransactionGraph,
235 ipScriptSession :: Maybe ScriptSession,
238 ipScriptSession :: Maybe ScriptSession,
236− ipLocalNode :: LocalNode,
237− ipTransport :: Transport, -- we hold onto this so that we can close it gracefully
238 ipLocks :: Maybe (LockFile, MVar LockFileHash) -- nothing when NoPersistence
239 ipLocks :: Maybe (LockFile, MVar LockFileHash) -- nothing when NoPersistence
239 }
240 }
240
241
241−data RemoteProcessConnectionConf = RemoteProcessConnectionConf {
242+data RemoteConnectionConf = RemoteConnectionConf {
242− rLocalNode :: LocalNode,
243+ rConn :: RPCConnection
243− rProcessId :: ProcessId, --remote processId
244− rTransport :: Transport --the TCP socket transport
245 }
244 }
246
245
247data Connection = InProcessConnection InProcessConnectionConf |
246data Connection = InProcessConnection InProcessConnectionConf |
248− RemoteProcessConnection RemoteProcessConnectionConf
247+ RemoteConnection RemoteConnectionConf
249
248
250-- | There are several reasons why a connection can fail.
249-- | There are several reasons why a connection can fail.
251data ConnectionError = SetupDatabaseDirectoryError PersistenceError |
250data ConnectionError = SetupDatabaseDirectoryError PersistenceError |
@@ -258,39 +257,6 @@ data ConnectionError = SetupDatabaseDirectoryError PersistenceError |
258remoteDBLookupName :: DatabaseName -> String
257remoteDBLookupName :: DatabaseName -> String
259remoteDBLookupName = (++) "db-"
258remoteDBLookupName = (++) "db-"
260
259
261−createLocalNode :: IO (LocalNode, Transport)
262−createLocalNode = do
263−#if MIN_VERSION_network_transport_tcp(0,7,0)
264− eLocalTransport <- createTransport (defaultTCPAddr "127.0.0.1" "0") defaultTCPParameters
265−#elif MIN_VERSION_network_transport_tcp(0,6,0)
266− eLocalTransport <- createTransport "127.0.0.1" "0" (\sn -> ("127.0.0.1", sn)) defaultTCPParameters
267−#else
268− eLocalTransport <- createTransport "127.0.0.1" "0" defaultTCPParameters
269−#endif
270− case eLocalTransport of
271− Left err -> error ("failed to create transport: " ++ show err)
272− Right localTransport -> do
273− localNode <- newLocalNode localTransport initRemoteTable
274− pure (localNode, localTransport)
275−
276−notificationListener :: NotificationCallback -> Process ()
277−notificationListener callback = do
278− --pid <- getSelfPid
279− --liftIO $ putStrLn $ "LISTENER THREAD START " ++ show pid
280− _ <- forever $
281− receiveWait [
282− match (\(NotificationMessage eNots) ->
283− --say $ "NOTIFICATION: " ++ show eNots
284− -- when notifications are thrown, they are not adjusted for the current schema which could be problematic, but we don't have access to the current session here
285− liftIO $ mapM_ (uncurry callback) (M.toList eNots)
286− )
287− ]
288− --say "LISTENER THREAD EXIT"
289− pure ()
290−
291−startNotificationListener :: LocalNode -> NotificationCallback -> IO ProcessId
292−startNotificationListener localNode callback = forkProcess localNode (notificationListener callback)
293−
294createScriptSession :: [String] -> IO (Maybe ScriptSession)
260createScriptSession :: [String] -> IO (Maybe ScriptSession)
295createScriptSession ghcPkgPaths = do
261createScriptSession ghcPkgPaths = do
296 eScriptSession <- initScriptSession ghcPkgPaths
262 eScriptSession <- initScriptSession ghcPkgPaths
@@ -312,8 +278,6 @@ connectProjectM36 (InProcessConnectionInfo strat notificationCallback ghcPkgPath
312 graphTvar <- newTVarIO freshGraph
278 graphTvar <- newTVarIO freshGraph
313 clientNodes <- StmSet.newIO
279 clientNodes <- StmSet.newIO
314 sessions <- StmMap.newIO
280 sessions <- StmMap.newIO
315− (localNode, transport) <- createLocalNode
316− notificationPid <- startNotificationListener localNode notificationCallback
317 mScriptSession <- createScriptSession ghcPkgPaths
281 mScriptSession <- createScriptSession ghcPkgPaths
318
282
319 let conn = InProcessConnection InProcessConnectionConf {
283 let conn = InProcessConnection InProcessConnectionConf {
@@ -322,22 +286,27 @@ connectProjectM36 (InProcessConnectionInfo strat notificationCallback ghcPkgPath
322 ipSessions = sessions,
286 ipSessions = sessions,
323 ipTransactionGraph = graphTvar,
287 ipTransactionGraph = graphTvar,
324 ipScriptSession = mScriptSession,
288 ipScriptSession = mScriptSession,
325− ipLocalNode = localNode,
326− ipTransport = transport,
327 ipLocks = Nothing}
289 ipLocks = Nothing}
328− addClientNode conn notificationPid
329 pure (Right conn)
290 pure (Right conn)
330 MinimalPersistence dbdir -> connectPersistentProjectM36 strat NoDiskSync dbdir freshGraph notificationCallback ghcPkgPaths
291 MinimalPersistence dbdir -> connectPersistentProjectM36 strat NoDiskSync dbdir freshGraph notificationCallback ghcPkgPaths
331 CrashSafePersistence dbdir -> connectPersistentProjectM36 strat FsyncDiskSync dbdir freshGraph notificationCallback ghcPkgPaths
292 CrashSafePersistence dbdir -> connectPersistentProjectM36 strat FsyncDiskSync dbdir freshGraph notificationCallback ghcPkgPaths
332
293
333−connectProjectM36 (RemoteProcessConnectionInfo databaseName serverNodeId notificationCallback) = do
294+connectProjectM36 (RemoteConnectionInfo databaseName hostName servicePort notificationCallback) = do
334− connStatus <- newEmptyMVar
335− (localNode, transport) <- createLocalNode
336− let dbName = remoteDBLookupName databaseName
337 --putStrLn $ "Connecting to " ++ show serverNodeId ++ " " ++ dbName
295 --putStrLn $ "Connecting to " ++ show serverNodeId ++ " " ++ dbName
338− notificationListenerPid <- startNotificationListener localNode notificationCallback
296+ --TODO- add notification callback thread
339− runProcess localNode $ do
297+ let resolutionHints = defaultHints { addrFlags = [AI_NUMERICHOST, AI_NUMERICSERV],
340− --even a failed connection retains an open socket!
298+ addrSocketType = Stream
299+ }
300+ resolved <- getAddrInfo (Just resolutionHints) (Just hostName) (Just servicePort)
301+ case resolved of
302+ [] -> error ("DNS resolution failed for" <> hostName <> ":" <> servicePort)
303+ addrInfo:_ -> do
304+ --supports IPv4 only for now
305+ let (SockAddrInet port addr) = addrAddress addrInfo
306+ conn <- RPC.connect (const (pure ())) (hostAddressToTuple addr) port
307+ --TODO handle connection errors!
308+ pure (Right (RemoteConnection (RemoteConnectionConf conn)))
309+ {-
341 mServerProcessId <- whereisRemote serverNodeId dbName
310 mServerProcessId <- whereisRemote serverNodeId dbName
342 case mServerProcessId of
311 case mServerProcessId of
343 Nothing -> liftIO $ putMVar connStatus $ Left (NoSuchDatabaseByNameError databaseName)
312 Nothing -> liftIO $ putMVar connStatus $ Left (NoSuchDatabaseByNameError databaseName)
@@ -346,8 +315,9 @@ connectProjectM36 (RemoteProcessConnectionInfo databaseName serverNodeId notific
346 if not loginConfirmation then
315 if not loginConfirmation then
347 liftIO $ putMVar connStatus (Left LoginError)
316 liftIO $ putMVar connStatus (Left LoginError)
348 else
317 else
349− liftIO $ putMVar connStatus (Right $ RemoteProcessConnection RemoteProcessConnectionConf {rLocalNode = localNode, rProcessId = serverProcessId, rTransport = transport})
318+ liftIO $ putMVar connStatus (Right $ RemoteProcessConnection RemoteProcessConnectionConf {rConn = )
350 takeMVar connStatus
319 takeMVar connStatus
320+-}
351
321
352connectPersistentProjectM36 :: PersistenceStrategy ->
322connectPersistentProjectM36 :: PersistenceStrategy ->
353 DiskSync ->
323 DiskSync ->
@@ -372,7 +342,6 @@ connectPersistentProjectM36 strat sync dbdir freshGraph notificationCallback ghc
372 tvarGraph <- newTVarIO graph'
342 tvarGraph <- newTVarIO graph'
373 sessions <- StmMap.newIO
343 sessions <- StmMap.newIO
374 clientNodes <- StmSet.newIO
344 clientNodes <- StmSet.newIO
375− (localNode, transport) <- createLocalNode
376 lockMVar <- newMVar digest
345 lockMVar <- newMVar digest
377 let conn = InProcessConnection InProcessConnectionConf {
346 let conn = InProcessConnection InProcessConnectionConf {
378 ipPersistenceStrategy = strat,
347 ipPersistenceStrategy = strat,
@@ -380,13 +349,9 @@ connectPersistentProjectM36 strat sync dbdir freshGraph notificationCallback ghc
380 ipSessions = sessions,
349 ipSessions = sessions,
381 ipTransactionGraph = tvarGraph,
350 ipTransactionGraph = tvarGraph,
382 ipScriptSession = mScriptSession,
351 ipScriptSession = mScriptSession,
383− ipLocalNode = localNode,
384− ipTransport = transport,
385 ipLocks = Just (lockFileH, lockMVar)
352 ipLocks = Just (lockFileH, lockMVar)
386 }
353 }
387
354
388− notificationPid <- startNotificationListener localNode notificationCallback
389− addClientNode conn notificationPid
390 pure (Right conn)
355 pure (Right conn)
391
356
392-- | Create a new session at the transaction id and return the session's Id.
357-- | Create a new session at the transaction id and return the session's Id.
@@ -394,7 +359,7 @@ createSessionAtCommit :: Connection -> TransactionId -> IO (Either RelationalErr
394createSessionAtCommit conn@(InProcessConnection _) commitId = do
359createSessionAtCommit conn@(InProcessConnection _) commitId = do
395 newSessionId <- nextRandom
360 newSessionId <- nextRandom
396 atomically $ createSessionAtCommit_ commitId newSessionId conn
361 atomically $ createSessionAtCommit_ commitId newSessionId conn
397−createSessionAtCommit conn@(RemoteProcessConnection _) uuid = remoteCall conn (CreateSessionAtCommit uuid)
362+createSessionAtCommit conn@(RemoteConnection _) uuid = remoteCall conn (CreateSessionAtCommit uuid)
398
363
399createSessionAtCommit_ :: TransactionId -> SessionId -> Connection -> STM (Either RelationalError SessionId)
364createSessionAtCommit_ :: TransactionId -> SessionId -> Connection -> STM (Either RelationalError SessionId)
400createSessionAtCommit_ commitId newSessionId (InProcessConnection conf) = do
365createSessionAtCommit_ commitId newSessionId (InProcessConnection conf) = do
@@ -411,7 +376,7 @@ createSessionAtCommit_ commitId newSessionId (InProcessConnection conf) = do
411 Nothing -> do
376 Nothing -> do
412 StmMap.insert (Session freshDiscon defaultSchemaName) newSessionId sessions
377 StmMap.insert (Session freshDiscon defaultSchemaName) newSessionId sessions
413 pure $ Right newSessionId
378 pure $ Right newSessionId
414−createSessionAtCommit_ _ _ (RemoteProcessConnection _) = error "createSessionAtCommit_ called on remote connection"
379+createSessionAtCommit_ _ _ (RemoteConnection _) = error "createSessionAtCommit_ called on remote connection"
415
380
416-- | Call 'createSessionAtHead' with a transaction graph's head's name to create a new session pinned to that head. This function returns a 'SessionId' which can be used in other function calls to reference the point in the transaction graph.
381-- | Call 'createSessionAtHead' with a transaction graph's head's name to create a new session pinned to that head. This function returns a 'SessionId' which can be used in other function calls to reference the point in the transaction graph.
417createSessionAtHead :: Connection -> HeadName -> IO (Either RelationalError SessionId)
382createSessionAtHead :: Connection -> HeadName -> IO (Either RelationalError SessionId)
@@ -423,18 +388,13 @@ createSessionAtHead conn@(InProcessConnection conf) headn = do
423 case transactionForHead headn graph of
388 case transactionForHead headn graph of
424 Nothing -> pure $ Left (NoSuchHeadNameError headn)
389 Nothing -> pure $ Left (NoSuchHeadNameError headn)
425 Just trans -> createSessionAtCommit_ (transactionId trans) newSessionId conn
390 Just trans -> createSessionAtCommit_ (transactionId trans) newSessionId conn
426−createSessionAtHead conn@(RemoteProcessConnection _) headn = remoteCall conn (CreateSessionAtHead headn)
391+createSessionAtHead conn@(RemoteConnection _) headn = remoteCall conn (CreateSessionAtHead headn)
427−
428−-- | Used internally for server connections to keep track of remote nodes for the purpose of sending notifications later.
429−addClientNode :: Connection -> ProcessId -> IO ()
430−addClientNode (RemoteProcessConnection _) _ = error "addClientNode called on remote connection"
431−addClientNode (InProcessConnection conf) newProcessId = atomically (StmSet.insert newProcessId (ipClientNodes conf))
432
392
433-- | Discards a session, eliminating any uncommitted changes present in the session.
393-- | Discards a session, eliminating any uncommitted changes present in the session.
434closeSession :: SessionId -> Connection -> IO ()
394closeSession :: SessionId -> Connection -> IO ()
435closeSession sessionId (InProcessConnection conf) =
395closeSession sessionId (InProcessConnection conf) =
436 atomically $ StmMap.delete sessionId (ipSessions conf)
396 atomically $ StmMap.delete sessionId (ipSessions conf)
437−closeSession sessionId conn@(RemoteProcessConnection _) = remoteCall conn (CloseSession sessionId)
397+closeSession sessionId conn@(RemoteConnection _) = remoteCall conn (CloseSession sessionId)
438
398
439-- | 'close' cleans up the database access connection and closes any relevant sockets.
399-- | 'close' cleans up the database access connection and closes any relevant sockets.
440close :: Connection -> IO ()
400close :: Connection -> IO ()
@@ -447,22 +407,18 @@ close (InProcessConnection conf) = do
447 StmMap.deleteAll sessions
407 StmMap.deleteAll sessions
448#endif
408#endif
449 pure ()
409 pure ()
450− closeLocalNode (ipLocalNode conf)
451− closeTransport (ipTransport conf)
452 let mLocks = ipLocks conf
410 let mLocks = ipLocks conf
453 case mLocks of
411 case mLocks of
454 Nothing -> pure ()
412 Nothing -> pure ()
455 Just (lockFileH, _) -> closeLockFile lockFileH
413 Just (lockFileH, _) -> closeLockFile lockFileH
456
414
457−close conn@(RemoteProcessConnection conf) = do
415+close (RemoteConnection (RemoteConnectionConf conn)) = do
458− _ <- remoteCall conn Logout :: IO Bool
416+ RPC.close conn
459− closeLocalNode (rLocalNode conf)
460− closeTransport (rTransport conf)
461
417
462--used only by the server EntryPoints
418--used only by the server EntryPoints
463closeRemote_ :: Connection -> IO ()
419closeRemote_ :: Connection -> IO ()
464closeRemote_ (InProcessConnection _) = error "invalid call of closeRemote_ on InProcessConnection"
420closeRemote_ (InProcessConnection _) = error "invalid call of closeRemote_ on InProcessConnection"
465−closeRemote_ (RemoteProcessConnection conf) = runProcess (rLocalNode conf) (reconnect (rProcessId conf))
421+closeRemote_ (RemoteConnection (RemoteConnectionConf conn)) = RPC.close conn
466
422
467 --we need to actually close the localNode's connection to the remote
423 --we need to actually close the localNode's connection to the remote
468--within the database server, we must catch and handle all exception lest they take down the database process- this handling might be different for other use-cases
424--within the database server, we must catch and handle all exception lest they take down the database process- this handling might be different for other use-cases
@@ -473,35 +429,20 @@ excEither = handle handler
473 where
429 where
474 handler exc | Just (_ :: AsyncException) <- fromException exc = throwIO exc
430 handler exc | Just (_ :: AsyncException) <- fromException exc = throwIO exc
475 | otherwise = pure (Left (UnhandledExceptionError (show exc)))
431 | otherwise = pure (Left (UnhandledExceptionError (show exc)))
476−
477−runProcessResult :: LocalNode -> Process a -> IO a
478−runProcessResult localNode proc = do
479− ret <- newEmptyMVar
480− runProcess localNode $ do
481− val <- proc
482− liftIO $ putMVar ret val
483− takeMVar ret
484
432
433+{-
485safeLogin :: Login -> ProcessId -> Process Bool
434safeLogin :: Login -> ProcessId -> Process Bool
486safeLogin login procId = do
435safeLogin login procId = do
487 ret <- call procId login
436 ret <- call procId login
488 case ret of
437 case ret of
489 Left (_ :: ServerError) -> pure False
438 Left (_ :: ServerError) -> pure False
490 Right val -> pure val
439 Right val -> pure val
440+-}
491
441
492−remoteCall :: (Binary a, Binary b, Typeable a, Typeable b) => Connection -> a -> IO b
442+remoteCall :: (Serialise a, Serialise b) => Connection -> a -> IO b
493remoteCall (InProcessConnection _ ) _ = error "remoteCall called on local connection"
443remoteCall (InProcessConnection _ ) _ = error "remoteCall called on local connection"
494−remoteCall (RemoteProcessConnection conf) arg = runProcessResult localNode $ do
444+remoteCall (RemoteConnection conf) arg = error "not implemented"
495− ret <- safeCall serverProcessId arg
445+
496− case ret of
497− Left err -> error ("server died: " ++ show err)
498− Right ret' -> case ret' of
499− Left RequestTimeoutError -> liftIO (throwIO RequestTimeoutException)
500− Left (ProcessDiedError _) -> liftIO (throwIO RemoteProcessDiedException)
501− Right val -> pure val
502− where
503− localNode = rLocalNode conf
504− serverProcessId = rProcessId conf
505
446
506sessionForSessionId :: SessionId -> Sessions -> STM (Either RelationalError Session)
447sessionForSessionId :: SessionId -> Sessions -> STM (Either RelationalError Session)
507sessionForSessionId sessionId sessions =
448sessionForSessionId sessionId sessions =
@@ -536,7 +477,7 @@ currentSchemaName sessionId (InProcessConnection conf) = atomically $ do
536 case eSession of
477 case eSession of
537 Left err -> pure (Left err)
478 Left err -> pure (Left err)
538 Right session -> pure (Right (Sess.schemaName session))
479 Right session -> pure (Right (Sess.schemaName session))
539−currentSchemaName sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveCurrentSchemaName sessionId)
480+currentSchemaName sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveCurrentSchemaName sessionId)
540
481
541-- | Switch to the named isomorphic schema.
482-- | Switch to the named isomorphic schema.
542setCurrentSchemaName :: SessionId -> Connection -> SchemaName -> IO (Either RelationalError ())
483setCurrentSchemaName :: SessionId -> Connection -> SchemaName -> IO (Either RelationalError ())
@@ -548,7 +489,7 @@ setCurrentSchemaName sessionId (InProcessConnection conf) sname = atomically $ d
548 Right session -> case Sess.setSchemaName sname session of
489 Right session -> case Sess.setSchemaName sname session of
549 Left err -> pure (Left err)
490 Left err -> pure (Left err)
550 Right newSession -> StmMap.insert newSession sessionId sessions >> pure (Right ())
491 Right newSession -> StmMap.insert newSession sessionId sessions >> pure (Right ())
551−setCurrentSchemaName sessionId conn@(RemoteProcessConnection _) sname = remoteCall conn (ExecuteSetCurrentSchema sessionId sname)
492+setCurrentSchemaName sessionId conn@(RemoteConnection _) sname = remoteCall conn (ExecuteSetCurrentSchema sessionId sname)
552
493
553-- | Execute a relational expression in the context of the session and connection. Relational expressions are queries and therefore cannot alter the database.
494-- | Execute a relational expression in the context of the session and connection. Relational expressions are queries and therefore cannot alter the database.
554executeRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
495executeRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
@@ -572,7 +513,7 @@ executeRelationalExpr sessionId (InProcessConnection conf) expr = excEither $ at
572 Right rel -> pure (force (Right rel)) -- this is necessary so that any undefined/error exceptions are spit out here
513 Right rel -> pure (force (Right rel)) -- this is necessary so that any undefined/error exceptions are spit out here
573 Left err -> pure (Left err)
514 Left err -> pure (Left err)
574
515
575−executeRelationalExpr sessionId conn@(RemoteProcessConnection _) relExpr = remoteCall conn (ExecuteRelationalExpr sessionId relExpr)
516+executeRelationalExpr sessionId conn@(RemoteConnection _) relExpr = remoteCall conn (ExecuteRelationalExpr sessionId relExpr)
576
517
577-- | Execute a database context expression in the context of the session and connection. Database expressions modify the current session's disconnected transaction but cannot modify the transaction graph.
518-- | Execute a database context expression in the context of the session and connection. Database expressions modify the current session's disconnected transaction but cannot modify the transaction graph.
578executeDatabaseContextExpr :: SessionId -> Connection -> DatabaseContextExpr -> IO (Either RelationalError ())
519executeDatabaseContextExpr :: SessionId -> Connection -> DatabaseContextExpr -> IO (Either RelationalError ())
@@ -606,7 +547,7 @@ executeDatabaseContextExpr sessionId (InProcessConnection conf) expr = excEither
606 newSession = Session newDiscon (Sess.schemaName session)
547 newSession = Session newDiscon (Sess.schemaName session)
607 StmMap.insert newSession sessionId sessions
548 StmMap.insert newSession sessionId sessions
608 pure (Right ())
549 pure (Right ())
609−executeDatabaseContextExpr sessionId conn@(RemoteProcessConnection _) dbExpr = remoteCall conn (ExecuteDatabaseContextExpr sessionId dbExpr)
550+executeDatabaseContextExpr sessionId conn@(RemoteConnection _) dbExpr = remoteCall conn (ExecuteDatabaseContextExpr sessionId dbExpr)
610
551
611-- | Similar to a git rebase, 'autoMergeToHead' atomically creates a temporary branch and merges it to the latest commit of the branch referred to by the 'HeadName' and commits the merge. This is useful to reduce incidents of 'TransactionIsNotAHeadError's but at the risk of merge errors (thus making it similar to rebasing). Alternatively, as an optimization, if a simple commit is possible (meaning that the head has not changed), then a fast-forward commit takes place instead.
552-- | Similar to a git rebase, 'autoMergeToHead' atomically creates a temporary branch and merges it to the latest commit of the branch referred to by the 'HeadName' and commits the merge. This is useful to reduce incidents of 'TransactionIsNotAHeadError's but at the risk of merge errors (thus making it similar to rebasing). Alternatively, as an optimization, if a simple commit is possible (meaning that the head has not changed), then a fast-forward commit takes place instead.
612autoMergeToHead :: SessionId -> Connection -> MergeStrategy -> HeadName -> IO (Either RelationalError ())
553autoMergeToHead :: SessionId -> Connection -> MergeStrategy -> HeadName -> IO (Either RelationalError ())
@@ -635,7 +576,7 @@ autoMergeToHead sessionId (InProcessConnection conf) strat headName' = do
635 Left err -> pure (Left err)
576 Left err -> pure (Left err)
636 Right ((discon', graph'), transactionIdsAdded) ->
577 Right ((discon', graph'), transactionIdsAdded) ->
637 pure (Right (discon', graph', transactionIdsAdded))
578 pure (Right (discon', graph', transactionIdsAdded))
638−autoMergeToHead sessionId conn@(RemoteProcessConnection _) strat headName' = remoteCall conn (ExecuteAutoMergeToHead sessionId strat headName')
579+autoMergeToHead sessionId conn@(RemoteConnection _) strat headName' = remoteCall conn (ExecuteAutoMergeToHead sessionId strat headName')
639
580
640-- | Execute a database context IO-monad-based expression for the given session and connection. `DatabaseContextIOExpr`s modify the DatabaseContext but cannot be purely implemented.
581-- | Execute a database context IO-monad-based expression for the given session and connection. `DatabaseContextIOExpr`s modify the DatabaseContext but cannot be purely implemented.
641--this is almost completely identical to executeDatabaseContextExpr above
582--this is almost completely identical to executeDatabaseContextExpr above
@@ -661,7 +602,7 @@ executeDatabaseContextIOExpr sessionId (InProcessConnection conf) expr = excEith
661 context' = RE.dbc_context newState
602 context' = RE.dbc_context newState
662 atomically $ StmMap.insert newSession sessionId sessions
603 atomically $ StmMap.insert newSession sessionId sessions
663 pure (Right ())
604 pure (Right ())
664−executeDatabaseContextIOExpr sessionId conn@(RemoteProcessConnection _) dbExpr = remoteCall conn (ExecuteDatabaseContextIOExpr sessionId dbExpr)
605+executeDatabaseContextIOExpr sessionId conn@(RemoteConnection _) dbExpr = remoteCall conn (ExecuteDatabaseContextIOExpr sessionId dbExpr)
665
606
666{-
607{-
667executeGraphExprSTM_ :: TransactionId -> SessionId -> Session -> Sessions -> TransactionGraphOperator -> TransactionGraph -> TVar TransactionGraph -> STM (Either RelationalError (TransactionGraph, DisconnectedTransaction)
608executeGraphExprSTM_ :: TransactionId -> SessionId -> Session -> Sessions -> TransactionGraphOperator -> TransactionGraph -> TVar TransactionGraph -> STM (Either RelationalError (TransactionGraph, DisconnectedTransaction)
@@ -788,7 +729,7 @@ executeGraphExpr sessionId (InProcessConnection conf) graphExpr = excEither $ do
788 sendNotifications nodesToNotify (ipLocalNode conf) notsToFire
729 sendNotifications nodesToNotify (ipLocalNode conf) notsToFire
789 pure Nothing
730 pure Nothing
790-}
731-}
791−executeGraphExpr sessionId conn@(RemoteProcessConnection _) graphExpr = remoteCall conn (ExecuteGraphExpr sessionId graphExpr)
732+executeGraphExpr sessionId conn@(RemoteConnection _) graphExpr = remoteCall conn (ExecuteGraphExpr sessionId graphExpr)
792
733
793-- | A trans-graph expression is a relational query executed against the entirety of a transaction graph.
734-- | A trans-graph expression is a relational query executed against the entirety of a transaction graph.
794executeTransGraphRelationalExpr :: SessionId -> Connection -> TransGraphRelationalExpr -> IO (Either RelationalError Relation)
735executeTransGraphRelationalExpr :: SessionId -> Connection -> TransGraphRelationalExpr -> IO (Either RelationalError Relation)
@@ -799,7 +740,7 @@ executeTransGraphRelationalExpr _ (InProcessConnection conf) tgraphExpr = excEit
799{- case runReader (RE.evalRelationalExpr relExpr) (RE.mkRelationalExprState DBC.empty) of
740{- case runReader (RE.evalRelationalExpr relExpr) (RE.mkRelationalExprState DBC.empty) of
800 Left err -> pure (Left err)
741 Left err -> pure (Left err)
801 Right rel -> pure (force (Right rel))-}
742 Right rel -> pure (force (Right rel))-}
802−executeTransGraphRelationalExpr sessionId conn@(RemoteProcessConnection _) tgraphExpr = remoteCall conn (ExecuteTransGraphRelationalExpr sessionId tgraphExpr)
743+executeTransGraphRelationalExpr sessionId conn@(RemoteConnection _) tgraphExpr = remoteCall conn (ExecuteTransGraphRelationalExpr sessionId tgraphExpr)
803
744
804-- | Schema expressions manipulate the isomorphic schemas for the current 'DatabaseContext'.
745-- | Schema expressions manipulate the isomorphic schemas for the current 'DatabaseContext'.
805executeSchemaExpr :: SessionId -> Connection -> Schema.SchemaExpr -> IO (Either RelationalError ())
746executeSchemaExpr :: SessionId -> Connection -> Schema.SchemaExpr -> IO (Either RelationalError ())
@@ -822,23 +763,24 @@ executeSchemaExpr sessionId (InProcessConnection conf) schemaExpr = atomically $
822 newSession = Session (DisconnectedTransaction (Discon.parentId discon) newSchemas False) (Sess.schemaName session)
763 newSession = Session (DisconnectedTransaction (Discon.parentId discon) newSchemas False) (Sess.schemaName session)
823 StmMap.insert newSession sessionId sessions
764 StmMap.insert newSession sessionId sessions
824 pure (Right ())
765 pure (Right ())
825−executeSchemaExpr sessionId conn@(RemoteProcessConnection _) schemaExpr = remoteCall conn (ExecuteSchemaExpr sessionId schemaExpr)
766+executeSchemaExpr sessionId conn@(RemoteConnection _) schemaExpr = remoteCall conn (ExecuteSchemaExpr sessionId schemaExpr)
826
767
827-- | After modifying a 'DatabaseContext', 'commit' the transaction to the transaction graph at the head which the session is referencing. This will also trigger checks for any notifications which need to be propagated.
768-- | After modifying a 'DatabaseContext', 'commit' the transaction to the transaction graph at the head which the session is referencing. This will also trigger checks for any notifications which need to be propagated.
828commit :: SessionId -> Connection -> IO (Either RelationalError ())
769commit :: SessionId -> Connection -> IO (Either RelationalError ())
829commit sessionId conn@(InProcessConnection _) = executeGraphExpr sessionId conn Commit
770commit sessionId conn@(InProcessConnection _) = executeGraphExpr sessionId conn Commit
830−commit sessionId conn@(RemoteProcessConnection _) = remoteCall conn (ExecuteGraphExpr sessionId Commit)
771+commit sessionId conn@(RemoteConnection _) = remoteCall conn (ExecuteGraphExpr sessionId Commit)
831−
772+
773+{-
832−sendNotifications :: [ProcessId] -> LocalNode -> EvaluatedNotifications -> IO ()
774+sendNotifications :: EvaluatedNotifications -> IO ()
833−sendNotifications pids localNode nots = mapM_ sendNots pids
775+sendNotifications nots = mapM_ sendNots pids
834 where
776 where
835 sendNots remoteClientPid =
777 sendNots remoteClientPid =
836 unless (M.null nots) $ runProcess localNode $ send remoteClientPid (NotificationMessage nots)
778 unless (M.null nots) $ runProcess localNode $ send remoteClientPid (NotificationMessage nots)
837−
779+ -}
838-- | Discard any changes made in the current 'Session' and 'DatabaseContext'. This resets the disconnected transaction to reference the original database context of the parent transaction and is a very cheap operation.
780-- | Discard any changes made in the current 'Session' and 'DatabaseContext'. This resets the disconnected transaction to reference the original database context of the parent transaction and is a very cheap operation.
839rollback :: SessionId -> Connection -> IO (Either RelationalError ())
781rollback :: SessionId -> Connection -> IO (Either RelationalError ())
840rollback sessionId conn@(InProcessConnection _) = executeGraphExpr sessionId conn Rollback
782rollback sessionId conn@(InProcessConnection _) = executeGraphExpr sessionId conn Rollback
841−rollback sessionId conn@(RemoteProcessConnection _) = remoteCall conn (ExecuteGraphExpr sessionId Rollback)
783+rollback sessionId conn@(RemoteConnection _) = remoteCall conn (ExecuteGraphExpr sessionId Rollback)
842
784
843-- | Write the transaction graph to disk. This function can be used to incrementally write new transactions to disk.
785-- | Write the transaction graph to disk. This function can be used to incrementally write new transactions to disk.
844processTransactionGraphPersistence :: PersistenceStrategy -> [TransactionId] -> TransactionGraph -> IO ()
786processTransactionGraphPersistence :: PersistenceStrategy -> [TransactionId] -> TransactionGraph -> IO ()
@@ -854,7 +796,7 @@ readGraphTransactionIdDigest (CrashSafePersistence dbdir) = readGraphTransaction
854-- | Return a relation whose type would match that of the relational expression if it were executed. This is useful for checking types and validating a relational expression's types.
796-- | Return a relation whose type would match that of the relational expression if it were executed. This is useful for checking types and validating a relational expression's types.
855typeForRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
797typeForRelationalExpr :: SessionId -> Connection -> RelationalExpr -> IO (Either RelationalError Relation)
856typeForRelationalExpr sessionId conn@(InProcessConnection _) relExpr = atomically $ typeForRelationalExprSTM sessionId conn relExpr
798typeForRelationalExpr sessionId conn@(InProcessConnection _) relExpr = atomically $ typeForRelationalExprSTM sessionId conn relExpr
857−typeForRelationalExpr sessionId conn@(RemoteProcessConnection _) relExpr = remoteCall conn (ExecuteTypeForRelationalExpr sessionId relExpr)
799+typeForRelationalExpr sessionId conn@(RemoteConnection _) relExpr = remoteCall conn (ExecuteTypeForRelationalExpr sessionId relExpr)
858
800
859typeForRelationalExprSTM :: SessionId -> Connection -> RelationalExpr -> STM (Either RelationalError Relation)
801typeForRelationalExprSTM :: SessionId -> Connection -> RelationalExpr -> STM (Either RelationalError Relation)
860typeForRelationalExprSTM sessionId (InProcessConnection conf) relExpr = do
802typeForRelationalExprSTM sessionId (InProcessConnection conf) relExpr = do
@@ -891,7 +833,7 @@ inclusionDependencies sessionId (InProcessConnection conf) = do
891 else
833 else
892 pure (Schema.inclusionDependenciesInSchema schema (B.inclusionDependencies context))
834 pure (Schema.inclusionDependenciesInSchema schema (B.inclusionDependencies context))
893
835
894−inclusionDependencies sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveInclusionDependencies sessionId)
836+inclusionDependencies sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveInclusionDependencies sessionId)
895
837
896typeConstructorMapping :: SessionId -> Connection -> IO (Either RelationalError TypeConstructorMapping)
838typeConstructorMapping :: SessionId -> Connection -> IO (Either RelationalError TypeConstructorMapping)
897typeConstructorMapping sessionId (InProcessConnection conf) = do
839typeConstructorMapping sessionId (InProcessConnection conf) = do
@@ -902,7 +844,7 @@ typeConstructorMapping sessionId (InProcessConnection conf) = do
902 Left err -> pure $ Left err
844 Left err -> pure $ Left err
903 Right (session, _) -> --warning, no schema support for typeconstructors
845 Right (session, _) -> --warning, no schema support for typeconstructors
904 pure (Right (B.typeConstructorMapping (Sess.concreteDatabaseContext session)))
846 pure (Right (B.typeConstructorMapping (Sess.concreteDatabaseContext session)))
905−typeConstructorMapping sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveTypeConstructorMapping sessionId)
847+typeConstructorMapping sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveTypeConstructorMapping sessionId)
906
848
907-- | Return an optimized database expression which is logically equivalent to the input database expression. This function can be used to determine which expression will actually be evaluated.
849-- | Return an optimized database expression which is logically equivalent to the input database expression. This function can be used to determine which expression will actually be evaluated.
908planForDatabaseContextExpr :: SessionId -> Connection -> DatabaseContextExpr -> IO (Either RelationalError GraphRefDatabaseContextExpr)
850planForDatabaseContextExpr :: SessionId -> Connection -> DatabaseContextExpr -> IO (Either RelationalError GraphRefDatabaseContextExpr)
@@ -922,7 +864,7 @@ planForDatabaseContextExpr sessionId (InProcessConnection conf) dbExpr = do
922 else -- don't show any optimization because the current optimization infrastructure relies on access to the base context- this probably underscores the need for each schema to have its own DatabaseContext, even if it is generated on-the-fly-}
864 else -- don't show any optimization because the current optimization infrastructure relies on access to the base context- this probably underscores the need for each schema to have its own DatabaseContext, even if it is generated on-the-fly-}
923 pure (Left NonConcreteSchemaPlanError)
865 pure (Left NonConcreteSchemaPlanError)
924
866
925−planForDatabaseContextExpr sessionId conn@(RemoteProcessConnection _) dbExpr = remoteCall conn (RetrievePlanForDatabaseContextExpr sessionId dbExpr)
867+planForDatabaseContextExpr sessionId conn@(RemoteConnection _) dbExpr = remoteCall conn (RetrievePlanForDatabaseContextExpr sessionId dbExpr)
926
868
927-- | Return a relation which represents the current state of the global transaction graph. The attributes are
869-- | Return a relation which represents the current state of the global transaction graph. The attributes are
928-- * current- boolean attribute representing whether or not the current session references this transaction
870-- * current- boolean attribute representing whether or not the current session references this transaction
@@ -940,7 +882,7 @@ transactionGraphAsRelation sessionId (InProcessConnection conf) = do
940 Right session ->
882 Right session ->
941 graphAsRelation (Sess.disconnectedTransaction session) <$> readTVar tvar
883 graphAsRelation (Sess.disconnectedTransaction session) <$> readTVar tvar
942
884
943−transactionGraphAsRelation sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveTransactionGraph sessionId)
885+transactionGraphAsRelation sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveTransactionGraph sessionId)
944
886
945-- | Returns the names and types of the relation variables in the current 'Session'.
887-- | Returns the names and types of the relation variables in the current 'Session'.
946relationVariablesAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
888relationVariablesAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
@@ -962,7 +904,7 @@ relationVariablesAsRelation sessionId (InProcessConnection conf) = do
962 let schemaContext = context {relationVariables = relvars }
904 let schemaContext = context {relationVariables = relvars }
963 pure $ RE.relationVariablesAsRelation schemaContext graph
905 pure $ RE.relationVariablesAsRelation schemaContext graph
964
906
965−relationVariablesAsRelation sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveRelationVariableSummary sessionId)
907+relationVariablesAsRelation sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveRelationVariableSummary sessionId)
966
908
967-- | Returns the names and types of the atom functions in the current 'Session'.
909-- | Returns the names and types of the atom functions in the current 'Session'.
968atomFunctionsAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
910atomFunctionsAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
@@ -975,7 +917,7 @@ atomFunctionsAsRelation sessionId (InProcessConnection conf) = do
975 Right (session, _) ->
917 Right (session, _) ->
976 pure (AF.atomFunctionsAsRelation (atomFunctions (concreteDatabaseContext session)))
918 pure (AF.atomFunctionsAsRelation (atomFunctions (concreteDatabaseContext session)))
977
919
978−atomFunctionsAsRelation sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveAtomFunctionSummary sessionId)
920+atomFunctionsAsRelation sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveAtomFunctionSummary sessionId)
979
921
980databaseContextFunctionsAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
922databaseContextFunctionsAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
981databaseContextFunctionsAsRelation sessionId (InProcessConnection conf) = do
923databaseContextFunctionsAsRelation sessionId (InProcessConnection conf) = do
@@ -987,7 +929,7 @@ databaseContextFunctionsAsRelation sessionId (InProcessConnection conf) = do
987 Right (session, _) ->
929 Right (session, _) ->
988 pure (DCF.databaseContextFunctionsAsRelation (dbcFunctions (concreteDatabaseContext session)))
930 pure (DCF.databaseContextFunctionsAsRelation (dbcFunctions (concreteDatabaseContext session)))
989
931
990−databaseContextFunctionsAsRelation sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveDatabaseContextFunctionSummary sessionId)
932+databaseContextFunctionsAsRelation sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveDatabaseContextFunctionSummary sessionId)
991
933
992-- | Returns the transaction id for the connection's disconnected transaction committed parent transaction.
934-- | Returns the transaction id for the connection's disconnected transaction committed parent transaction.
993headTransactionId :: SessionId -> Connection -> IO (Either RelationalError TransactionId)
935headTransactionId :: SessionId -> Connection -> IO (Either RelationalError TransactionId)
@@ -998,7 +940,7 @@ headTransactionId sessionId (InProcessConnection conf) = do
998 case eSession of
940 case eSession of
999 Left err -> pure (Left err)
941 Left err -> pure (Left err)
1000 Right session -> pure $ Right (Sess.parentId session)
942 Right session -> pure $ Right (Sess.parentId session)
1001−headTransactionId sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveHeadTransactionId sessionId)
943+headTransactionId sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveHeadTransactionId sessionId)
1002
944
1003headNameSTM_ :: SessionId -> Sessions -> TVar TransactionGraph -> STM (Either RelationalError HeadName)
945headNameSTM_ :: SessionId -> Sessions -> TVar TransactionGraph -> STM (Either RelationalError HeadName)
1004headNameSTM_ sessionId sessions graphTvar = do
946headNameSTM_ sessionId sessions graphTvar = do
@@ -1018,7 +960,7 @@ headName sessionId (InProcessConnection conf) = do
1018 let sessions = ipSessions conf
960 let sessions = ipSessions conf
1019 graphTvar = ipTransactionGraph conf
961 graphTvar = ipTransactionGraph conf
1020 atomically (headNameSTM_ sessionId sessions graphTvar)
962 atomically (headNameSTM_ sessionId sessions graphTvar)
1021−headName sessionId conn@(RemoteProcessConnection _) = remoteCall conn (ExecuteHeadName sessionId)
963+headName sessionId conn@(RemoteConnection _) = remoteCall conn (ExecuteHeadName sessionId)
1022
964
1023-- | Returns a listing of all available atom types.
965-- | Returns a listing of all available atom types.
1024atomTypesAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
966atomTypesAsRelation :: SessionId -> Connection -> IO (Either RelationalError Relation)
@@ -1032,7 +974,7 @@ atomTypesAsRelation sessionId (InProcessConnection conf) = do
1032 case typesAsRelation (B.typeConstructorMapping (Sess.concreteDatabaseContext session)) of
974 case typesAsRelation (B.typeConstructorMapping (Sess.concreteDatabaseContext session)) of
1033 Left err -> pure (Left err)
975 Left err -> pure (Left err)
1034 Right rel -> pure (Right rel)
976 Right rel -> pure (Right rel)
1035−atomTypesAsRelation sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveAtomTypesAsRelation sessionId)
977+atomTypesAsRelation sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveAtomTypesAsRelation sessionId)
1036
978
1037disconnectedTransactionIsDirty :: SessionId -> Connection -> IO (Either RelationalError Bool)
979disconnectedTransactionIsDirty :: SessionId -> Connection -> IO (Either RelationalError Bool)
1038disconnectedTransactionIsDirty sessionId (InProcessConnection conf) = do
980disconnectedTransactionIsDirty sessionId (InProcessConnection conf) = do
@@ -1043,12 +985,12 @@ disconnectedTransactionIsDirty sessionId (InProcessConnection conf) = do
1043 Left err -> pure (Left err)
985 Left err -> pure (Left err)
1044 Right session ->
986 Right session ->
1045 pure (Right (isDirty session))
987 pure (Right (isDirty session))
1046−disconnectedTransactionIsDirty sessionId conn@(RemoteProcessConnection _) = remoteCall conn (RetrieveSessionIsDirty sessionId)
988+disconnectedTransactionIsDirty sessionId conn@(RemoteConnection _) = remoteCall conn (RetrieveSessionIsDirty sessionId)
1047
989
1048--used only for testing- we expect this to throw an exception
990--used only for testing- we expect this to throw an exception
1049callTestTimeout_ :: SessionId -> Connection -> IO Bool
991callTestTimeout_ :: SessionId -> Connection -> IO Bool
1050callTestTimeout_ _ (InProcessConnection _) = error "bad testing call"
992callTestTimeout_ _ (InProcessConnection _) = error "bad testing call"
1051−callTestTimeout_ sessionId conn@(RemoteProcessConnection _) = remoteCall conn (TestTimeout sessionId)
993+callTestTimeout_ sessionId conn@(RemoteConnection _) = remoteCall conn (TestTimeout sessionId)
1052
994
1053--used in tests only
995--used in tests only
1054transactionGraph_ :: Connection -> IO TransactionGraph
996transactionGraph_ :: Connection -> IO TransactionGraph
@@ -1133,7 +1075,7 @@ commitLock_ sessionId conf stmBlock = do
1133 Right (notsToFire, nodesToNotify, newGraph, transactionIdsToPersist) -> do
1075 Right (notsToFire, nodesToNotify, newGraph, transactionIdsToPersist) -> do
1134 --update filesystem database, if necessary
1076 --update filesystem database, if necessary
1135 processTransactionGraphPersistence strat transactionIdsToPersist newGraph
1077 processTransactionGraphPersistence strat transactionIdsToPersist newGraph
1136− sendNotifications nodesToNotify (ipLocalNode conf) notsToFire
1078+ --sendNotifications nodesToNotify (ipLocalNode conf) notsToFire
1137 pure (Right ())
1079 pure (Right ())
1138{-
1080{-
1139writeDisconAndGraph_ :: TVar TransactionGraph -> SessionId -> Session -> Sessions -> DisconnectedTransaction -> TransactionGraph -> STM ()
1081writeDisconAndGraph_ :: TVar TransactionGraph -> SessionId -> Session -> Sessions -> DisconnectedTransaction -> TransactionGraph -> STM ()
@@ -1193,7 +1135,7 @@ executeDataFrameExpr sessionId conn@(InProcessConnection _) dfExpr = do
1193 let dFrame' = maybe dFrame (`DF.drop'` dFrame) (DF.offset dfExpr)
1135 let dFrame' = maybe dFrame (`DF.drop'` dFrame) (DF.offset dfExpr)
1194 dFrame'' = maybe dFrame' (`DF.take'` dFrame') (DF.limit dfExpr)
1136 dFrame'' = maybe dFrame' (`DF.take'` dFrame') (DF.limit dfExpr)
1195 pure (Right dFrame'')
1137 pure (Right dFrame'')
1196−executeDataFrameExpr sessionId conn@(RemoteProcessConnection _) dfExpr = remoteCall conn (ExecuteDataFrameExpr sessionId dfExpr)
1138+executeDataFrameExpr sessionId conn@(RemoteConnection _) dfExpr = remoteCall conn (ExecuteDataFrameExpr sessionId dfExpr)
1197
1139
1198validateMerkleHashes :: SessionId -> Connection -> IO (Either RelationalError ())
1140validateMerkleHashes :: SessionId -> Connection -> IO (Either RelationalError ())
1199validateMerkleHashes sessionId (InProcessConnection conf) = do
1141validateMerkleHashes sessionId (InProcessConnection conf) = do
@@ -1207,4 +1149,4 @@ validateMerkleHashes sessionId (InProcessConnection conf) = do
1207 case Graph.validateMerkleHashes graph of
1149 case Graph.validateMerkleHashes graph of
1208 Left merkleErrs -> pure $ Left $ someErrors (map (\(MerkleValidationError tid expected actual) -> MerkleHashValidationError tid expected actual) merkleErrs)
1150 Left merkleErrs -> pure $ Left $ someErrors (map (\(MerkleValidationError tid expected actual) -> MerkleHashValidationError tid expected actual) merkleErrs)
1209 Right () -> pure (Right ())
1151 Right () -> pure (Right ())
1210−validateMerkleHashes sessionId conn@RemoteProcessConnection{} = remoteCall conn (ExecuteValidateMerkleHashes sessionId)
1152+validateMerkleHashes sessionId conn@RemoteConnection{} = remoteCall conn (ExecuteValidateMerkleHashes sessionId)
src/lib/ProjectM36/Serialise/Base.hs+1−2
@@ -3,7 +3,7 @@
3--Serialise instances for ProjectM36.Base data types- orphan instance city
3--Serialise instances for ProjectM36.Base data types- orphan instance city
4module ProjectM36.Serialise.Base where
4module ProjectM36.Serialise.Base where
5import Codec.Winery hiding (Schema)
5import Codec.Winery hiding (Schema)
6−import Codec.Winery.Internal hiding (Schema)
6+import Codec.Winery.Internal
7import Control.Monad
7import Control.Monad
8import ProjectM36.Base
8import ProjectM36.Base
9import ProjectM36.MerkleHash
9import ProjectM36.MerkleHash
@@ -45,7 +45,6 @@ deriving via WineryVariant (ExtendTupleExprBase a) instance Serialise a => Seria
45deriving via WineryVariant Schema instance Serialise Schema
45deriving via WineryVariant Schema instance Serialise Schema
46deriving via WineryVariant MergeStrategy instance Serialise MergeStrategy
46deriving via WineryVariant MergeStrategy instance Serialise MergeStrategy
47
47
48−
49fromWordsTup :: (Word32, Word32, Word32, Word32) -> TransactionId
48fromWordsTup :: (Word32, Word32, Word32, Word32) -> TransactionId
50fromWordsTup (a,b,c,d) = fromWords a b c d
49fromWordsTup (a,b,c,d) = fromWords a b c d
51
50
src/lib/ProjectM36/Server/RemoteCallTypes.hs+3−68
@@ -14,12 +14,13 @@ import GHC.Generics
14import Data.Binary
14import Data.Binary
15import Control.Distributed.Process (ProcessId)
15import Control.Distributed.Process (ProcessId)
16import Codec.Winery
16import Codec.Winery
17+import Network.RPC.Curryer.Client
17
18
18data Request = Login |
19data Request = Login |
19 Logout |
20 Logout |
20 ExecuteRelationalExpr SessionId RelationalExpr |
21 ExecuteRelationalExpr SessionId RelationalExpr |
21 ExecuteDataFrameExpr SessionId DataFrameExpr |
22 ExecuteDataFrameExpr SessionId DataFrameExpr |
22− ExecuteDatabaseConextExpr SessionId DatabaseContextExpr |
23+ ExecuteDatabaseContextExpr SessionId DatabaseContextExpr |
23 ExecuteDatabaseContextIOExpr SessionId DatabaseContextIOExpr |
24 ExecuteDatabaseContextIOExpr SessionId DatabaseContextIOExpr |
24 ExecuteGraphExpr SessionId TransactionGraphOperator |
25 ExecuteGraphExpr SessionId TransactionGraphOperator |
25 ExecuteTransGraphRelationalExpr SessionId TransGraphRelationalExpr |
26 ExecuteTransGraphRelationalExpr SessionId TransGraphRelationalExpr |
@@ -63,70 +64,4 @@ data Response = RelationResp (Either RelationalError Relation) |
63 deriving (Generic)
64 deriving (Generic)
64 deriving Serialise via WineryVariant Response
65 deriving Serialise via WineryVariant Response
65
66
66−
67+type RPCConnection = Connection Response
67−
68−{-
69−
70−{-# ANN module ("HLint: ignore Use newtype instead of data" :: String) #-}
71−-- | The initial login message. The argument should be the process id of the initiating client. This ProcessId will receive notification callbacks.
72−data Login = Login ProcessId
73− deriving (Binary, Generic)
74−
75−data Logout = Logout
76− deriving (Binary, Generic)
77−data ExecuteRelationalExpr = ExecuteRelationalExpr SessionId RelationalExpr
78− deriving (Binary, Generic)
79−data ExecuteDataFrameExpr = ExecuteDataFrameExpr SessionId DataFrameExpr
80− deriving (Binary, Generic)
81−data ExecuteDatabaseContextExpr = ExecuteDatabaseContextExpr SessionId DatabaseContextExpr
82− deriving (Binary, Generic)
83−data ExecuteDatabaseContextIOExpr = ExecuteDatabaseContextIOExpr SessionId DatabaseContextIOExpr
84− deriving (Binary, Generic)
85−data ExecuteGraphExpr = ExecuteGraphExpr SessionId TransactionGraphOperator
86− deriving (Binary, Generic)
87−data ExecuteTransGraphRelationalExpr = ExecuteTransGraphRelationalExpr SessionId TransGraphRelationalExpr
88− deriving (Binary, Generic)
89−data ExecuteHeadName = ExecuteHeadName SessionId
90− deriving (Binary, Generic)
91−data ExecuteTypeForRelationalExpr = ExecuteTypeForRelationalExpr SessionId RelationalExpr
92− deriving (Binary, Generic)
93−data ExecuteSchemaExpr = ExecuteSchemaExpr SessionId SchemaExpr
94− deriving (Binary, Generic)
95−data ExecuteSetCurrentSchema = ExecuteSetCurrentSchema SessionId SchemaName
96− deriving (Binary, Generic)
97−data RetrieveInclusionDependencies = RetrieveInclusionDependencies SessionId
98− deriving (Binary, Generic)
99−data RetrievePlanForDatabaseContextExpr = RetrievePlanForDatabaseContextExpr SessionId DatabaseContextExpr
100− deriving (Binary, Generic)
101−data RetrieveTransactionGraph = RetrieveTransactionGraph SessionId
102− deriving (Binary, Generic)
103−data RetrieveHeadTransactionId = RetrieveHeadTransactionId SessionId
104− deriving (Binary, Generic)
105−data CreateSessionAtCommit = CreateSessionAtCommit TransactionId
106− deriving (Binary, Generic)
107−data CreateSessionAtHead = CreateSessionAtHead HeadName
108− deriving (Binary, Generic)
109−data CloseSession = CloseSession SessionId
110− deriving (Binary, Generic)
111−data RetrieveAtomTypesAsRelation = RetrieveAtomTypesAsRelation SessionId
112− deriving (Binary, Generic)
113−data RetrieveRelationVariableSummary = RetrieveRelationVariableSummary SessionId
114− deriving (Binary, Generic)
115−data RetrieveAtomFunctionSummary = RetrieveAtomFunctionSummary SessionId
116− deriving (Binary, Generic)
117−data RetrieveDatabaseContextFunctionSummary = RetrieveDatabaseContextFunctionSummary SessionId
118− deriving (Binary, Generic)
119−data RetrieveCurrentSchemaName = RetrieveCurrentSchemaName SessionId
120− deriving (Binary, Generic)
121−data TestTimeout = TestTimeout SessionId
122− deriving (Binary, Generic)
123−data RetrieveSessionIsDirty = RetrieveSessionIsDirty SessionId
124− deriving (Binary, Generic)
125−data ExecuteAutoMergeToHead = ExecuteAutoMergeToHead SessionId MergeStrategy HeadName
126− deriving (Binary, Generic)
127−data RetrieveTypeConstructorMapping = RetrieveTypeConstructorMapping SessionId
128− deriving (Binary, Generic)
129−
130−data ExecuteValidateMerkleHashes = ExecuteValidateMerkleHashes SessionId
131− deriving (Binary, Generic)
132−-}