1module Control.Distributed.Process.Internal.Spawn
10import Data.Typeable (Typeable)
11import Control.Monad.IO.Class (liftIO)
12import Control.Applicative ((<$>))
13import Control.Monad.Reader (ask)
14import Control.Concurrent.MVar (newEmptyMVar, takeMVar, putMVar)
15import Control.Distributed.Static
21import Control.Distributed.Process.Internal.Types
26 , ProcessMonitorNotification(..)
27 , NodeMonitorNotification(..)
31 , LocalProcess(processNode)
34import Control.Distributed.Process.Serializable (Serializable, SerializableDict)
35import Control.Distributed.Process.Internal.Closure.BuiltIn
47import Control.Distributed.Process.Internal.Primitives
66-- For more information about 'Closure', see
67-- "Control.Distributed.Process.Closure".
70spawn :: NodeId -> Closure (Process ()) -> Process ProcessId
73 mRef <- monitorNode nid
74 sRef <- spawnAsync nid (cpDelay us proc)
76 matchIf (\(DidSpawn ref _) -> ref == sRef) $ \(DidSpawn _ pid) -> do
80 , matchIf (\(NodeMonitorNotification ref _ _) -> ref == mRef) $ \_ ->
81 return (nullProcessId nid)
84-- | Spawn a process and link to it
86-- Note that this is just the sequential composition of 'spawn' and 'link'.
87-- (The "Unified" semantics that underlies Cloud Haskell does not even support
88-- a synchronous link operation)
89spawnLink :: NodeId -> Closure (Process ()) -> Process ProcessId
90spawnLink nid proc = do
95-- | Like 'spawnLink', but monitor the spawned process
96spawnMonitor :: NodeId -> Closure (Process ()) -> Process (ProcessId, MonitorRef)
97spawnMonitor nid proc = do
102-- | Run a process remotely and wait for it to reply
104-- We monitor the remote process: if it dies before it can send a reply, we die
107-- For more information about 'Static', 'SerializableDict', and 'Closure', see
108-- "Control.Distributed.Process.Closure".
111call :: Serializable a
112 => Static (SerializableDict a)
114 -> Closure (Process a)
116call dict nid proc = do
118 (pid, mRef) <- spawnMonitor nid (proc `bindCP` cpSend dict us)
119 -- We are guaranteed to receive the reply before the monitor notification
120 -- (if a reply is sent at all)
121 -- NOTE: This might not be true if we switch to unreliable delivery.
122 mResult <- receiveWait
123 [ match (return . Right)
124 , matchIf (\(ProcessMonitorNotification ref _ _) -> ref == mRef)
125 (\(ProcessMonitorNotification _ _ reason) -> return (Left reason))
129 -- Wait for the monitor message so that we the mailbox doesn't grow
131 [ matchIf (\(ProcessMonitorNotification ref _ _) -> ref == mRef)
132 (\(ProcessMonitorNotification {}) -> return ())
134 -- Clean up connection to pid
138 fail $ "call: remote process died: " ++ show err
140-- | Spawn a child process, have the child link to the parent and the parent
142spawnSupervised :: NodeId
143 -> Closure (Process ())
144 -> Process (ProcessId, MonitorRef)
145spawnSupervised nid proc = do
147 them <- spawn nid (cpLink us `seqCP` proc)
151-- | Spawn a new process, supplying it with a new 'ReceivePort' and return
152-- the corresponding 'SendPort'.
153spawnChannel :: forall a. Typeable a => Static (SerializableDict a)
155 -> Closure (ReceivePort a -> Process ())
156 -> Process (SendPort a)
157spawnChannel dict nid proc = do
159 _ <- spawn nid (go us)
162 go :: ProcessId -> Closure (Process ())
163 go pid = cpNewChan dict
165 (cpSend (sdictSendPort dict) pid `splitCP` proc)
167 (idCP `closureCompose` staticClosure sndStatic)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list