@@ -71,7 +71,6 @@ import Control.Distributed.Process.Internal.Types
7171 , NCMsg(..)
7272 , ProcessSignal(..)
7373 , payloadToMessage
74− , payloadToId
7574 , localPidCounter
7675 , localPidUnique
7776 , localProcessWithId
@@ -88,6 +87,8 @@ import Control.Distributed.Process.Internal.Types
8887 , createMessage
8988 , MessageT
9089 , runMessageT
90+ , TypedChannel(..)
91+ , Identifier(..)
9192 )
9293import Control.Distributed.Process.Serializable (Serializable)
9394import Control.Distributed.Process.Internal.MessageT
@@ -152,6 +153,8 @@ forkProcess node proc = modifyMVar (localState node) $ \st -> do
152153 }
153154 pst <- newMVar LocalProcessState { _monitorCounter = 0
154155 , _spawnCounter = 0
156+ , _channelCounter = 0
157+ , _typedChannels = Map.empty
155158 }
156159 queue <- newCQueue
157160 (_, lproc) <- fixIO $ \ ~(tid, _) -> do
@@ -168,8 +171,8 @@ forkProcess node proc = modifyMVar (localState node) $ \st -> do
168171 modifyMVar_ (localState node) $
169172 return . (localProcessWithId lpid ^= Nothing)
170173 writeChan (localCtrlChan node) NCMsg
171− { ctrlMsgSender = Left pid
172− , ctrlMsgSignal = Died (Left pid) reason
174+ { ctrlMsgSender = ProcessIdentifier pid
175+ , ctrlMsgSignal = Died (ProcessIdentifier pid) reason
173176 }
174177 return (tid', lproc)
175178
@@ -181,35 +184,45 @@ forkProcess node proc = modifyMVar (localState node) $ \st -> do
181184 )
182185
183186handleIncomingMessages :: LocalNode -> IO ()
184−handleIncomingMessages node = go [] Map.empty Set.empty
187+handleIncomingMessages node = go [] Map.empty Map.empty Set.empty
185188 where
186189 go :: [NT.ConnectionId] -- ^ Connections whose purpose we don't yet know
187190 -> Map NT.ConnectionId LocalProcess -- ^ Connections to local processes
191+ -> Map NT.ConnectionId TypedChannel -- ^ Connections to typed channels
188192 -> Set NT.ConnectionId -- ^ Connections to our controller
189193 -> IO ()
190− go uninitConns procConns ctrlConns = do
194+ go uninitConns procs chans ctrls = do
191195 event <- NT.receive endpoint
192196 case event of
193197 NT.ConnectionOpened cid _rel _theirAddr ->
194− go (cid : uninitConns) procConns ctrlConns
198+ go (cid : uninitConns) procs chans ctrls
195199 NT.Received cid payload ->
196− case Map.lookup cid procConns of
197− Just proc -> do
200+ case ( Map.lookup cid procs
201+ , Map.lookup cid chans
202+ , cid `Set.member` ctrls
203+ , cid `elem` uninitConns
204+ ) of
205+ (Just proc, _, _, _) -> do
198206 let msg = payloadToMessage payload
199207 enqueue (processQueue proc) msg
200− go uninitConns procConns ctrlConns
201− Nothing | cid `Set.member` ctrlConns -> do
208+ go uninitConns procs chans ctrls
209+ (_, Just (TypedChannel queue), _, _) -> do
210+ enqueue queue . decode . BSL.fromChunks $ payload
211+ go uninitConns procs chans ctrls
212+ (_, _, True, _) -> do
202213 writeChan ctrlChan (decode . BSL.fromChunks $ payload)
203− go uninitConns procConns ctrlConns
204− Nothing | cid `elem` uninitConns ->
205− case payloadToId payload of
206− Just lpid -> do
214+ go uninitConns procs chans ctrls
215+ (_, _, _, True) ->
216+ case decode (BSL.fromChunks payload) of
217+ ProcessIdentifier pid -> do
218+ let lpid = processLocalId pid
207219 mProc <- withMVar state $ return . (^. localProcessWithId lpid)
208220 case mProc of
209221 Just proc ->
210222 go (List.delete cid uninitConns)
211− (Map.insert cid proc procConns)
212− ctrlConns
223+ (Map.insert cid proc procs)
224+ chans
225+ ctrls
213226 Nothing ->
214227 -- Request for an unknown process.
215228 -- TODO: We should close the incoming connection here, but
@@ -217,22 +230,27 @@ handleIncomingMessages node = go [] Map.empty Set.empty
217230 -- functionality. Not sure what the right approach is.
218231 -- For now, we just drop the incoming messages
219232 go (List.delete cid uninitConns)
220− procConns
221− ctrlConns
222− Nothing ->
233+ procs
234+ chans
235+ ctrls
236+ ChannelIdentifier _chId ->
237+ fail "Connecting to typed channels not yet implemented"
238+ NodeIdentifier _ ->
223239 go (List.delete cid uninitConns)
224− procConns
225− (Set.insert cid ctrlConns)
226− _ ->
240+ procs
241+ chans
242+ (Set.insert cid ctrls)
243+ _ ->
227244 -- Unexpected message. We just drop it.
228− go uninitConns procConns ctrlConns
245+ go uninitConns procs chans ctrls
229246 NT.ConnectionClosed cid ->
230247 go (List.delete cid uninitConns)
231− (Map.delete cid procConns)
232− (Set.delete cid ctrlConns)
248+ (Map.delete cid procs)
249+ (Map.delete cid chans)
250+ (Set.delete cid ctrls)
233251 NT.ErrorEvent (NT.TransportError (NT.EventConnectionLost (Just theirAddr) _) _) -> do
234252 -- [Unified table 9, rule node_disconnect]
235− let nid = Right $ NodeId theirAddr
253+ let nid = NodeIdentifier $ NodeId theirAddr
236254 writeChan ctrlChan NCMsg
237255 { ctrlMsgSender = nid
238256 , ctrlMsgSignal = Died nid DiedDisconnect
@@ -291,23 +309,25 @@ nodeController = do
291309
292310 -- [Unified: Table 7, rule nc_forward]
293311 case destNid (ctrlMsgSignal msg) of
294− Just nid' | nid' /= localNodeId node -> lift $ sendBinary (Right nid') msg
295− _ -> return ()
312+ Just nid' | nid' /= localNodeId node ->
313+ lift $ sendBinary (NodeIdentifier nid') msg
314+ _ ->
315+ return ()
296316
297317 case msg of
298− NCMsg (Left from) (Link them) ->
318+ NCMsg (ProcessIdentifier from) (Link them) ->
299319 ncEffectMonitor from them Nothing
300− NCMsg (Left from) (Monitor them ref) ->
320+ NCMsg (ProcessIdentifier from) (Monitor them ref) ->
301321 ncEffectMonitor from them (Just ref)
302− NCMsg (Left from) (Unlink them) ->
322+ NCMsg (ProcessIdentifier from) (Unlink them) ->
303323 ncEffectUnlink from them
304− NCMsg (Left from) (Unmonitor ref) ->
324+ NCMsg (ProcessIdentifier from) (Unmonitor ref) ->
305325 ncEffectUnmonitor from ref
306− NCMsg _from (Died (Right nid) reason) ->
326+ NCMsg _from (Died (NodeIdentifier nid) reason) ->
307327 ncEffectNodeDied nid reason
308− NCMsg _from (Died (Left pid) reason) ->
328+ NCMsg _from (Died (ProcessIdentifier pid) reason) ->
309329 ncEffectProcessDied pid reason
310− NCMsg (Left from) (Spawn proc ref) ->
330+ NCMsg (ProcessIdentifier from) (Spawn proc ref) ->
311331 ncEffectSpawn from proc ref
312332 unexpected ->
313333 error $ "Unexpected message " ++ show unexpected
@@ -332,9 +352,9 @@ ncEffectMonitor from them mRef = do
332352 (False, True) -> -- [Unified: second rule]
333353 notifyDied from them DiedNoProc mRef
334354 (False, False) -> -- [Unified: third rule]
335− lift $ sendBinary (Right $ processNodeId from) NCMsg
336− { ctrlMsgSender = Right (localNodeId node)
337− , ctrlMsgSignal = Died (Left them) DiedNoProc
355+ lift $ sendBinary (NodeIdentifier $ processNodeId from) NCMsg
356+ { ctrlMsgSender = NodeIdentifier (localNodeId node)
357+ , ctrlMsgSignal = Died (ProcessIdentifier them) DiedNoProc
338358 }
339359
340360-- [Unified: Table 11]
@@ -398,7 +418,7 @@ ncEffectSpawn pid cProc ref = do
398418 forM_ mProc $ \proc -> do
399419 node <- lift getLocalNode
400420 pid' <- liftIO $ forkProcess node proc
401− lift $ sendMessage (Left pid) (DidSpawn ref pid')
421+ lift $ sendMessage (ProcessIdentifier pid) (DidSpawn ref pid')
402422
403423--------------------------------------------------------------------------------
404424-- Auxiliary --
@@ -419,20 +439,29 @@ notifyDied dest src reason mRef = do
419439 (False, _) ->
420440 -- TODO: why the change in sender? How does that affect 'reconnect' semantics?
421441 -- (see [Unified: Table 10]
422− lift $ sendBinary (Right $ processNodeId dest) NCMsg
423− { ctrlMsgSender = Right (localNodeId node)
424− , ctrlMsgSignal = Died (Left src) reason
442+ lift $ sendBinary (NodeIdentifier $ processNodeId dest) NCMsg
443+ { ctrlMsgSender = NodeIdentifier (localNodeId node)
444+ , ctrlMsgSignal = Died (ProcessIdentifier src) reason
425445 }
426446
427447-- | [Unified: Table 8]
428448destNid :: ProcessSignal -> Maybe NodeId
429−destNid (Link pid) = Just . processNodeId $ pid
430−destNid (Unlink pid) = Just . processNodeId $ pid
431−destNid (Monitor pid _) = Just . processNodeId $ pid
432−destNid (Unmonitor ref) = Just . processNodeId . monitorRefPid $ ref
433−destNid (Died (Right _) _) = Nothing
434−destNid (Died (Left _pid) _) = fail "destNid: TODO"
435−destNid (Spawn _ _) = Nothing
449+destNid (Link pid) =
450+ Just . processNodeId $ pid
451+destNid (Unlink pid) =
452+ Just . processNodeId $ pid
453+destNid (Monitor pid _) =
454+ Just . processNodeId $ pid
455+destNid (Unmonitor ref) =
456+ Just . processNodeId . monitorRefPid $ ref
457+destNid (Died (NodeIdentifier _) _) =
458+ Nothing
459+destNid (Died (ProcessIdentifier _pid) _) =
460+ fail "destNid: TODO"
461+destNid (Died (ChannelIdentifier _cid) _) =
462+ fail "destNid: TODO"
463+destNid (Spawn _ _) =
464+ Nothing
436465
437466-- | Check if a process is local to our own node
438467isLocal :: LocalNode -> ProcessId -> Bool