1{-# LANGUAGE RankNTypes #-}
2module Control.Distributed.Process.Internal.Spawn
11import Control.Distributed.Static
17import Control.Distributed.Process.Internal.Types
22 , ProcessMonitorNotification(..)
23 , NodeMonitorNotification(..)
29import Control.Distributed.Process.Serializable (Serializable, SerializableDict)
30import Control.Distributed.Process.Internal.Closure.BuiltIn
44import Control.Distributed.Process.Internal.Primitives
62-- For more information about 'Closure', see
63-- "Control.Distributed.Process.Closure".
66spawn :: NodeId -> Closure (Process ()) -> Process ProcessId
69 mRef <- monitorNode nid
70 sRef <- spawnAsync nid (cpDelayed us proc)
72 matchIf (\(DidSpawn ref _) -> ref == sRef) $ \(DidSpawn _ pid) -> do
76 , matchIf (\(NodeMonitorNotification ref _ _) -> ref == mRef) $ \_ ->
77 return (nullProcessId nid)
80-- | Spawn a process and link to it
82-- Note that this is just the sequential composition of 'spawn' and 'link'.
83-- (The "Unified" semantics that underlies Cloud Haskell does not even support
84-- a synchronous link operation)
85spawnLink :: NodeId -> Closure (Process ()) -> Process ProcessId
86spawnLink nid proc = do
91-- | Like 'spawnLink', but monitor the spawned process
92spawnMonitor :: NodeId -> Closure (Process ()) -> Process (ProcessId, MonitorRef)
93spawnMonitor nid proc = do
98-- | Run a process remotely and wait for it to reply
100-- We monitor the remote process: if it dies before it can send a reply, we die
103-- For more information about 'Static', 'SerializableDict', and 'Closure', see
104-- "Control.Distributed.Process.Closure".
107call :: Serializable a
108 => Static (SerializableDict a)
110 -> Closure (Process a)
112call dict nid proc = do
114 (pid, mRef) <- spawnMonitor nid (proc `bindCP`
115 cpSend dict us `seqCP`
116 -- Delay so the process does not terminate
117 -- before the response arrives.
118 cpDelayed us (returnCP sdictUnit ())
120 mResult <- receiveWait
121 [ match $ \a -> usend pid () >> return (Right a)
122 , matchIf (\(ProcessMonitorNotification ref _ _) -> ref == mRef)
123 (\(ProcessMonitorNotification _ _ reason) -> return (Left reason))
127 -- Wait for the monitor message so that we the mailbox doesn't grow
129 [ matchIf (\(ProcessMonitorNotification ref _ _) -> ref == mRef)
130 (\(ProcessMonitorNotification {}) -> return ())
132 -- Clean up connection to pid
136 fail $ "call: remote process died: " ++ show err
138-- | Spawn a child process, have the child link to the parent and the parent
140spawnSupervised :: NodeId
141 -> Closure (Process ())
142 -> Process (ProcessId, MonitorRef)
143spawnSupervised nid proc = do
145 them <- spawn nid (cpLink us `seqCP` proc)
149-- | Spawn a new process, supplying it with a new 'ReceivePort' and return
150-- the corresponding 'SendPort'.
151spawnChannel :: forall a. Serializable a => Static (SerializableDict a)
153 -> Closure (ReceivePort a -> Process ())
154 -> Process (SendPort a)
155spawnChannel dict nid proc = do
157 _ <- spawn nid (go us)
160 go :: ProcessId -> Closure (Process ())
161 go pid = cpNewChan dict
163 (cpSend (sdictSendPort dict) pid `splitCP` proc)
165 (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