git.iko.soy/distributed-process
on master help sign in
Support code for spawn (but no implementation yet)
commite57e0e35bcc0dda88639060ed70522bd1eb33754 authorEdsko de Vries <edsko@edsko.net> dateTue 19 Jun 2012, 17:13 (14 years ago) parent35e512d
4 files changed+85−30
distributed-process/src/Control/Distributed/Process.hs+32−14 distributed-process/src/Control/Distributed/Process/Internal/NodeController.hs+1−1 distributed-process/src/Control/Distributed/Process/Internal/Types.hs+10−1 distributed-process/tests/TestClosure.hs+42−14
distributed-process/src/Control/Distributed/Process.hs+32−14
@@ -15,7 +15,7 @@ module Control.Distributed.Process
1515 , expect
1616 , send
1717 , getSelfPid
18− , RemoteTable
18+ , spawn
1919 -- * Matching messages
2020 , Match
2121 , match
@@ -38,6 +38,7 @@ module Control.Distributed.Process
3838 , Closure
3939 , Static
4040 , unClosure
41+ , RemoteTable
4142 -- * Auxiliary API
4243 , catch
4344 , expectTimeout
@@ -78,6 +79,7 @@ import Control.Distributed.Process.Internal.Types
7879 , DidUnlink(..)
7980 , DiedReason(..)
8081 , SpawnRef(..)
82+ , DidSpawn(..)
8183 , NCMsg(..)
8284 , ProcessSignal(..)
8385 , monitorCounter
@@ -87,6 +89,7 @@ import Control.Distributed.Process.Internal.Types
8789 )
8890import Control.Distributed.Process.Internal.MessageT
8991 ( sendMessage
92+ , sendBinary
9093 , getLocalNode
9194 )
9295
@@ -171,21 +174,29 @@ getSelfPid = processId <$> ask
171174monitor :: ProcessId -> Process MonitorRef
172175monitor them = do
173176 monitorRef <- getMonitorRefFor them
174− postCtrlMsg $ Monitor them monitorRef
177+ sendCtrlMsg Nothing $ Monitor them monitorRef
175178 return monitorRef
176179
177180-- | Link to a remote process
178181link :: ProcessId -> Process ()
179−link = postCtrlMsg . Link
182+link = sendCtrlMsg Nothing . Link
180183
181184-- | Remove a monitor
182185unmonitor :: MonitorRef -> Process ()
183−unmonitor = postCtrlMsg . Unmonitor
186+unmonitor = sendCtrlMsg Nothing . Unmonitor
184187
185188-- | Remove a link
186189unlink :: ProcessId -> Process ()
187−unlink = postCtrlMsg . Unlink
190+unlink = sendCtrlMsg Nothing . Unlink
188191
192+-- | Spawn a process
193+spawn :: NodeId -> Closure (Process ()) -> Process ProcessId
194+spawn nid proc = do
195+ ref <- spawnAsync nid proc
196+ receiveWait [ matchIf (\(DidSpawn ref' _) -> ref == ref')
197+ (\(DidSpawn _ pid) -> return pid)
198+ ]
199+
189200--------------------------------------------------------------------------------
190201-- Matching --
191202--------------------------------------------------------------------------------
@@ -257,9 +268,9 @@ expectTimeout timeout = receiveTimeout timeout [match return]
257268--
258269-- ('spawn' is defined in terms of 'spawnAsync' and 'expect')
259270spawnAsync :: NodeId -> Closure (Process ()) -> Process SpawnRef
260−spawnAsync _nid proc = do
271+spawnAsync nid proc = do
261272 spawnRef <- getSpawnRef
262− postCtrlMsg (Spawn proc spawnRef)
273+ sendCtrlMsg (Just nid) $ Spawn proc spawnRef
263274 return spawnRef
264275
265276--------------------------------------------------------------------------------
@@ -284,14 +295,21 @@ getSpawnRef = do
284295 , SpawnRef counter
285296 )
286297
287−-- | Post a control message on the local node controller
288−postCtrlMsg :: ProcessSignal -> Process ()
289−postCtrlMsg signal = do
298+-- Send a control message
299+sendCtrlMsg :: Maybe NodeId -- ^ Nothing for the local node
300+ -> ProcessSignal -- ^ Message to send
301+ -> Process ()
302+sendCtrlMsg mNid signal = do
290303 us <- getSelfPid
291− ctrlChan <- localCtrlChan <$> lift getLocalNode
292− liftIO $ writeChan ctrlChan NCMsg { ctrlMsgSender = Left us
293− , ctrlMsgSignal = signal
294− }
304+ let msg = NCMsg { ctrlMsgSender = Left us
305+ , ctrlMsgSignal = signal
306+ }
307+ case mNid of
308+ Nothing -> do
309+ ctrlChan <- localCtrlChan <$> lift getLocalNode
310+ liftIO $ writeChan ctrlChan msg
311+ Just nid ->
312+ lift $ sendBinary (Right nid) msg
295313
296314lookupStatic :: Typeable a => String -> Process a
297315lookupStatic label = do
distributed-process/src/Control/Distributed/Process/Internal/NodeController.hs+1−1
@@ -105,7 +105,7 @@ nodeController = do
105105 NCMsg _from (Died (Left pid) reason) ->
106106 ncEffectProcessDied pid reason
107107 NCMsg _from (Spawn _ _) ->
108− fail "spawn not implemented"
108+ fail $ show (localNodeId node) ++ ": spawn not implemented"
109109 unexpected ->
110110 error $ "Unexpected message " ++ show unexpected
111111
distributed-process/src/Control/Distributed/Process/Internal/Types.hs+10−1
@@ -29,6 +29,7 @@ module Control.Distributed.Process.Internal.Types
2929 , DidUnmonitor(..)
3030 , DidUnlink(..)
3131 , SpawnRef(..)
32+ , DidSpawn(..)
3233 -- * Node controller internal data types
3334 , NCMsg(..)
3435 , ProcessSignal(..)
@@ -244,7 +245,11 @@ newtype DidUnlink = DidUnlink ProcessId
244245
245246-- | 'SpawnRef' are used to return pids of spawned processes
246247newtype SpawnRef = SpawnRef Int32
247− deriving (Show, Binary, Typeable)
248+ deriving (Show, Binary, Typeable, Eq)
249+
250+-- | (Asynchronius) reply from spawn
251+data DidSpawn = DidSpawn SpawnRef ProcessId
252+ deriving (Show, Typeable)
248253
249254--------------------------------------------------------------------------------
250255-- Node controller internal data types --
@@ -371,6 +376,10 @@ instance Binary (Closure a) where
371376 put (Closure (Static label) env) = put label >> put env
372377 get = Closure <$> (Static <$> get) <*> get
373378
379+instance Binary DidSpawn where
380+ put (DidSpawn ref pid) = put ref >> put pid
381+ get = DidSpawn <$> get <*> get
382+
374383--------------------------------------------------------------------------------
375384-- Accessors --
376385--------------------------------------------------------------------------------
distributed-process/tests/TestClosure.hs+42−14
@@ -19,15 +19,20 @@ putInt = flip putMVar
1919sendInt :: ProcessId -> Int -> Process ()
2020sendInt = send
2121
22−$(remotable ['addInt, 'putInt, 'sendInt])
22+sendPid :: ProcessId -> Process ()
23+sendPid toPid = do
24+ fromPid <- getSelfPid
25+ send toPid fromPid
26+
27+$(remotable ['addInt, 'putInt, 'sendInt, 'sendPid])
2328
2429testSendPureClosure :: Transport -> RemoteTable -> IO ()
25−testSendPureClosure transport metaData = do
30+testSendPureClosure transport rtable = do
2631 serverAddr <- newEmptyMVar
2732 serverDone <- newEmptyMVar
2833
2934 forkIO $ do
30− node <- newLocalNode transport metaData
35+ node <- newLocalNode transport rtable
3136 addr <- forkProcess node $ do
3237 cl <- expect
3338 fn <- unClosure cl :: Process (Int -> Int)
@@ -36,19 +41,19 @@ testSendPureClosure transport metaData = do
3641 putMVar serverAddr addr
3742
3843 forkIO $ do
39− node <- newLocalNode transport metaData
44+ node <- newLocalNode transport rtable
4045 theirAddr <- readMVar serverAddr
4146 runProcess node $ send theirAddr ($(mkClosure 'addInt) 5)
4247
4348 takeMVar serverDone
4449
4550testSendIOClosure :: Transport -> RemoteTable -> IO ()
46−testSendIOClosure transport metaData = do
51+testSendIOClosure transport rtable = do
4752 serverAddr <- newEmptyMVar
4853 serverDone <- newEmptyMVar
4954
5055 forkIO $ do
51− node <- newLocalNode transport metaData
56+ node <- newLocalNode transport rtable
5257 addr <- forkProcess node $ do
5358 cl <- expect
5459 io <- unClosure cl :: Process (MVar Int -> IO ())
@@ -60,19 +65,19 @@ testSendIOClosure transport metaData = do
6065 putMVar serverAddr addr
6166
6267 forkIO $ do
63− node <- newLocalNode transport metaData
68+ node <- newLocalNode transport rtable
6469 theirAddr <- readMVar serverAddr
6570 runProcess node $ send theirAddr ($(mkClosure 'putInt) 5)
6671
6772 takeMVar serverDone
6873
6974testSendProcClosure :: Transport -> RemoteTable -> IO ()
70−testSendProcClosure transport metaData = do
75+testSendProcClosure transport rtable = do
7176 serverAddr <- newEmptyMVar
7277 clientDone <- newEmptyMVar
7378
7479 forkIO $ do
75− node <- newLocalNode transport metaData
80+ node <- newLocalNode transport rtable
7681 addr <- forkProcess node $ do
7782 cl <- expect
7883 pr <- unClosure cl :: Process (Int -> Process ())
@@ -80,7 +85,7 @@ testSendProcClosure transport metaData = do
8085 putMVar serverAddr addr
8186
8287 forkIO $ do
83− node <- newLocalNode transport metaData
88+ node <- newLocalNode transport rtable
8489 theirAddr <- readMVar serverAddr
8590 runProcess node $ do
8691 pid <- getSelfPid
@@ -90,12 +95,35 @@ testSendProcClosure transport metaData = do
9095
9196 takeMVar clientDone
9297
98+testSpawn :: Transport -> RemoteTable -> IO ()
99+testSpawn transport rtable = do
100+ serverNodeAddr <- newEmptyMVar
101+ clientDone <- newEmptyMVar
102+
103+ forkIO $ do
104+ node <- newLocalNode transport rtable
105+ print (localNodeId node)
106+ putMVar serverNodeAddr (localNodeId node)
107+
108+ forkIO $ do
109+ node <- newLocalNode transport rtable
110+ nid <- readMVar serverNodeAddr
111+ runProcess node $ do
112+ pid <- getSelfPid
113+ pid' <- spawn nid ($(mkClosure 'sendPid) pid)
114+ pid'' <- expect
115+ True <- return $ pid' == pid''
116+ liftIO $ putMVar clientDone ()
117+
118+ takeMVar clientDone
119+
93120main :: IO ()
94121main = do
95122 Right transport <- createTransport "127.0.0.1" "8080" defaultTCPParameters
96− let metaData = __remoteTable initRemoteTable
123+ let rtable = __remoteTable initRemoteTable
97124 runTests
98− [ ("SendPureClosure", testSendPureClosure transport metaData)
99− , ("SendIOClosure", testSendIOClosure transport metaData)
100− , ("SendProcClosure", testSendProcClosure transport metaData)
125+ [ ("SendPureClosure", testSendPureClosure transport rtable)
126+ , ("SendIOClosure", testSendIOClosure transport rtable)
127+ , ("SendProcClosure", testSendProcClosure transport rtable)
128+ , ("Spawn", testSpawn transport rtable)
101129 ]