1module Control.Distributed.Process.Internal.Messaging
6 , closeImplicitReconnections
11import Data.Accessor ((^.), (^=))
12import Data.Binary (Binary, encode)
13import qualified Data.Map as Map (partitionWithKey, elems)
14import qualified Data.ByteString.Lazy as BSL (toChunks)
15import qualified Data.ByteString as BSS (ByteString)
16import Control.Distributed.Process.Serializable ()
18import Control.Concurrent (forkIO)
19import Control.Concurrent.Chan (writeChan)
20import Control.Exception (mask_)
21import Control.Monad (unless)
22import Control.Monad.IO.Class (liftIO)
23import Control.Monad.Reader (ask)
24import qualified Network.Transport as NT
29 , Reliability(ReliableOrdered)
32import Control.Distributed.Process.Internal.Types
33 ( LocalNode(localState, localEndPoint, localCtrlChan)
35 , modifyValidLocalState
36 , modifyValidLocalState_
39 , localConnectionBetween
46 , DiedReason(DiedDisconnect)
47 , ImplicitReconnect(WithImplicitReconnect)
53 , SendPortId(sendPortProcessId)
54 , Identifier(NodeIdentifier, ProcessIdentifier, SendPortIdentifier)
56import Control.Distributed.Process.Serializable (Serializable)
57import Data.Foldable (forM_)
59--------------------------------------------------------------------------------
61--------------------------------------------------------------------------------
63sendPayload :: LocalNode
69sendPayload node from to implicitReconnect payload = do
70 mConn <- connBetween node from to implicitReconnect
71 didSend <- case mConn of
73 didSend <- NT.send conn payload
75 Left _err -> return False
76 Right () -> return True
77 Nothing -> return False
79 writeChan (localCtrlChan node) NCMsg
81 , ctrlMsgSignal = Died (NodeIdentifier $ nodeOf to) DiedDisconnect
91sendBinary node from to implicitReconnect
92 = sendPayload node from to implicitReconnect . BSL.toChunks . encode
94sendMessage :: Serializable a
101sendMessage node from to implicitReconnect =
102 sendPayload node from to implicitReconnect . messageToPayload . createMessage
104setupConnBetween :: LocalNode
108 -> IO (Maybe NT.Connection)
109setupConnBetween node from to implicitReconnect = do
110 mConn <- NT.connect (localEndPoint node)
111 (nodeAddress . nodeOf $ to)
113 NT.defaultConnectHints
116 didSend <- NT.send conn (BSL.toChunks . encode $ to)
121 modifyValidLocalState_ node $
122 return . (localConnectionBetween from to ^= Just (conn, implicitReconnect))
127connBetween :: LocalNode
131 -> IO (Maybe NT.Connection)
132connBetween node from to implicitReconnect = do
133 mConn <- withValidLocalState node $
134 return . (^. localConnectionBetween from to)
139 setupConnBetween node from to implicitReconnect
141disconnect :: LocalNode -> Identifier -> Identifier -> IO ()
142disconnect node from to = mask_ $ do
143 mio <- modifyValidLocalState node $ \vst ->
144 case vst ^. localConnectionBetween from to of
146 return (vst, return ())
148 return ( localConnectionBetween from to ^= Nothing $ vst
153closeImplicitReconnections :: LocalNode -> Identifier -> IO ()
154closeImplicitReconnections node to = mask_ $ do
155 mconns <- modifyValidLocalState node $ \vst -> do
156 let shouldClose (_, to') (_, WithImplicitReconnect) = to `impliesDeathOf` to'
157 shouldClose _ _ = False
158 let (affected, unaffected) =
159 Map.partitionWithKey shouldClose (vst ^. localConnections)
160 return ( localConnections ^= unaffected $ vst
161 , map fst $ Map.elems affected
163 forM_ mconns $ forkIO . mapM_ NT.close
165-- | @a `impliesDeathOf` b@ is true if the death of @a@ (for instance, a node)
166-- implies the death of @b@ (for instance, a process on that node)
167impliesDeathOf :: Identifier
170NodeIdentifier nid `impliesDeathOf` NodeIdentifier nid' =
172NodeIdentifier nid `impliesDeathOf` ProcessIdentifier pid =
173 processNodeId pid == nid
174NodeIdentifier nid `impliesDeathOf` SendPortIdentifier cid =
175 processNodeId (sendPortProcessId cid) == nid
176ProcessIdentifier pid `impliesDeathOf` ProcessIdentifier pid' =
178ProcessIdentifier pid `impliesDeathOf` SendPortIdentifier cid =
179 sendPortProcessId cid == pid
180SendPortIdentifier cid `impliesDeathOf` SendPortIdentifier cid' =
182_ `impliesDeathOf` _ =
186-- Send a control message. Evaluates the message to HNF before sending it.
188-- The message shouldn't produce more errors when further evaluated. If
189-- evaluation threw errors the node controller or the receiver would crash when
191sendCtrlMsg :: Maybe NodeId -- ^ Nothing for the local node
192 -> ProcessSignal -- ^ Message to send
194sendCtrlMsg mNid signal = do
196 let msg = NCMsg { ctrlMsgSender = ProcessIdentifier (processId proc)
197 , ctrlMsgSignal = signal
201 liftIO $ writeChan (localCtrlChan (processNode proc)) $! msg
203 liftIO $ sendBinary (processNode proc)
204 (ProcessIdentifier (processId proc))
206 WithImplicitReconnect
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