@@ -76,7 +76,7 @@ import Data.UUID.V4 (nextRandom)
7676import Control.Concurrent.STM
7777import Data.Word
7878import Control.Distributed.Process (ProcessId, Process, receiveWait, send, match)
79−import Control.Exception (IOException, SomeException(..), handle)
79+import Control.Exception (IOException, SomeException(..), handle, AsyncException, throwIO, fromException, Exception)
8080import Control.Concurrent.MVar
8181import qualified Data.Map as M
8282import Control.Distributed.Process.Serializable (Serializable)
@@ -104,8 +104,10 @@ type NotificationCallback = NotificationName -> EvaluatedNotification -> IO ()
104104emptyNotificationCallback :: NotificationCallback
105105emptyNotificationCallback _ _ = pure ()
106106
107+type GhcPkgPath = String
108+
107109-- | Construct a 'ConnectionInfo' to describe how to make the 'Connection'.
108−data ConnectionInfo = InProcessConnectionInfo PersistenceStrategy NotificationCallback |
110+data ConnectionInfo = InProcessConnectionInfo PersistenceStrategy NotificationCallback [GhcPkgPath]|
109111 RemoteProcessConnectionInfo DatabaseName NodeId NotificationCallback
110112
111113type EvaluatedNotifications = M.Map NotificationName EvaluatedNotification
@@ -134,7 +136,7 @@ defaultHeadName :: HeadName
134136defaultHeadName = "master"
135137
136138defaultRemoteConnectionInfo :: ConnectionInfo
137−defaultRemoteConnectionInfo = RemoteProcessConnectionInfo defaultDatabaseName (createNodeId "127.0.0.1" defaultServerPort) emptyNotificationCallback
139+defaultRemoteConnectionInfo = RemoteProcessConnectionInfo defaultDatabaseName (createNodeId "127.0.0.1" defaultServerPort) emptyNotificationCallback
138140
139141-- | The 'Connection' represents either local or remote access to a database. All operations flow through the connection.
140142type ClientNodes = STMSet.Set ProcessId
@@ -152,7 +154,6 @@ data ConnectionError = SetupDatabaseDirectoryError PersistenceError |
152154remoteDBLookupName :: DatabaseName -> String
153155remoteDBLookupName = (++) "db-"
154156
155−
156157commonLocalNode :: IO (Either ConnectionError LocalNode)
157158commonLocalNode = do
158159 eLocalTransport <- createTransport "127.0.0.1" "0" defaultTCPParameters
@@ -184,7 +185,7 @@ startNotificationListener callback = do
184185-- | To create a 'Connection' to a remote or local database, create a connectionInfo and call 'connectProjectM36'.
185186connectProjectM36 :: ConnectionInfo -> IO (Either ConnectionError Connection)
186187--create a new in-memory database/transaction graph
187−connectProjectM36 (InProcessConnectionInfo strat notificationCallback) = do
188+connectProjectM36 (InProcessConnectionInfo strat notificationCallback ghcPkgPaths) = do
188189 freshId <- nextRandom
189190 let bootstrapContext = basicDatabaseContext
190191 freshGraph = bootstrapTransactionGraph freshId bootstrapContext
@@ -195,12 +196,12 @@ connectProjectM36 (InProcessConnectionInfo strat notificationCallback) = do
195196 clientNodes <- STMSet.newIO
196197 sessions <- STMMap.newIO
197198 notificationPid <- startNotificationListener notificationCallback
198− interpreterSession <- initScriptSession
199+ interpreterSession <- initScriptSession ghcPkgPaths
199200 let conn = InProcessConnection strat clientNodes sessions graphTvar interpreterSession
200201 addClientNode conn notificationPid
201202 pure (Right conn)
202− MinimalPersistence dbdir -> connectPersistentProjectM36 strat NoDiskSync dbdir freshGraph notificationCallback
203− CrashSafePersistence dbdir -> connectPersistentProjectM36 strat FsyncDiskSync dbdir freshGraph notificationCallback
203+ MinimalPersistence dbdir -> connectPersistentProjectM36 strat NoDiskSync dbdir freshGraph notificationCallback ghcPkgPaths
204+ CrashSafePersistence dbdir -> connectPersistentProjectM36 strat FsyncDiskSync dbdir freshGraph notificationCallback ghcPkgPaths
204205
205206connectProjectM36 (RemoteProcessConnectionInfo databaseName serverNodeId notificationCallback) = do
206207 connStatus <- newEmptyMVar
@@ -229,8 +230,9 @@ connectPersistentProjectM36 :: PersistenceStrategy ->
229230 FilePath ->
230231 TransactionGraph ->
231232 NotificationCallback ->
233+ [GhcPkgPath] ->
232234 IO (Either ConnectionError Connection)
233−connectPersistentProjectM36 strat sync dbdir freshGraph notificationCallback = do
235+connectPersistentProjectM36 strat sync dbdir freshGraph notificationCallback ghcPkgPaths = do
234236 err <- setupDatabaseDir sync dbdir freshGraph
235237 case err of
236238 Just err' -> return $ Left (SetupDatabaseDirectoryError err')
@@ -242,7 +244,7 @@ connectPersistentProjectM36 strat sync dbdir freshGraph notificationCallback = d
242244 tvarGraph <- newTVarIO graph'
243245 sessions <- STMMap.newIO
244246 clientNodes <- STMSet.newIO
245− scriptSession <- initScriptSession
247+ scriptSession <- initScriptSession ghcPkgPaths
246248 let conn = InProcessConnection strat clientNodes sessions tvarGraph scriptSession
247249 notificationPid <- startNotificationListener notificationCallback
248250 addClientNode conn notificationPid
@@ -308,12 +310,14 @@ close (RemoteProcessConnection localNode serverProcessId) = do
308310excMaybe :: IO (Maybe RelationalError) -> IO (Maybe RelationalError)
309311excMaybe m = handle handler m
310312 where
311− handler (exc :: SomeException) = pure (Just (UnhandledExceptionError (show exc)))
312−
313+ handler exc | Just (_ :: AsyncException) <- fromException exc = throwIO exc
314+ | otherwise = pure (Just (UnhandledExceptionError (show exc)))
315+
313316excEither :: IO (Either RelationalError a) -> IO (Either RelationalError a)
314317excEither m = handle handler m
315318 where
316− handler (exc :: SomeException) = pure (Left (UnhandledExceptionError (show exc)))
319+ handler exc | Just (_ :: AsyncException) <- fromException exc = throwIO exc
320+ | otherwise = pure (Left (UnhandledExceptionError (show exc)))
317321
318322runProcessResult :: LocalNode -> Process a -> IO a
319323runProcessResult localNode proc = do