module Control.Distributed.Process.Internal.Messaging
( sendPayload
, sendBinary
, sendMessage
, disconnect
, closeImplicitReconnections
, impliesDeathOf
, sendCtrlMsg
) where
import Data.Accessor ((^.), (^=))
import Data.Binary (Binary, encode)
import qualified Data.Map as Map (partitionWithKey, elems)
import qualified Data.ByteString.Lazy as BSL (toChunks)
import qualified Data.ByteString as BSS (ByteString)
import Control.Distributed.Process.Serializable ()
import Control.Concurrent (forkIO)
import Control.Concurrent.Chan (writeChan)
import Control.Exception (mask_)
import Control.Monad (unless)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Reader (ask)
import qualified Network.Transport as NT
( Connection
, send
, defaultConnectHints
, connect
, Reliability(ReliableOrdered)
, close
)
import Control.Distributed.Process.Internal.Types
( LocalNode(localEndPoint, localCtrlChan)
, withValidLocalState
, modifyValidLocalState
, modifyValidLocalState_
, Identifier
, localConnections
, localConnectionBetween
, nodeAddress
, nodeOf
, messageToPayload
, createMessage
, NCMsg(..)
, ProcessSignal(Died)
, DiedReason(DiedDisconnect)
, ImplicitReconnect(WithImplicitReconnect)
, NodeId(..)
, ProcessId(..)
, LocalNode(..)
, LocalProcess(..)
, Process(..)
, SendPortId(sendPortProcessId)
, Identifier(NodeIdentifier, ProcessIdentifier, SendPortIdentifier)
)
import Control.Distributed.Process.Serializable (Serializable)
import Data.Foldable (forM_)
sendPayload :: LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> [BSS.ByteString]
-> IO ()
sendPayload :: LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> [ByteString]
-> IO ()
sendPayload LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect [ByteString]
payload = do
Maybe Connection
mConn <- LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> IO (Maybe Connection)
connBetween LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect
Bool
didSend <- case Maybe Connection
mConn of
Just Connection
conn -> do
Either (TransportError SendErrorCode) ()
didSend <- Connection
-> [ByteString] -> IO (Either (TransportError SendErrorCode) ())
NT.send Connection
conn [ByteString]
payload
case Either (TransportError SendErrorCode) ()
didSend of
Left TransportError SendErrorCode
_err -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Right () -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
Maybe Connection
Nothing -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
didSend (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Chan NCMsg -> NCMsg -> IO ()
forall a. Chan a -> a -> IO ()
writeChan (LocalNode -> Chan NCMsg
localCtrlChan LocalNode
node) NCMsg
{ ctrlMsgSender :: Identifier
ctrlMsgSender = Identifier
to
, ctrlMsgSignal :: ProcessSignal
ctrlMsgSignal = Identifier -> DiedReason -> ProcessSignal
Died (NodeId -> Identifier
NodeIdentifier (NodeId -> Identifier) -> NodeId -> Identifier
forall a b. (a -> b) -> a -> b
$ Identifier -> NodeId
nodeOf Identifier
to) DiedReason
DiedDisconnect
}
sendBinary :: Binary a
=> LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> a
-> IO ()
sendBinary :: forall a.
Binary a =>
LocalNode
-> Identifier -> Identifier -> ImplicitReconnect -> a -> IO ()
sendBinary LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect
= LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> [ByteString]
-> IO ()
sendPayload LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect ([ByteString] -> IO ()) -> (a -> [ByteString]) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LazyByteString -> [ByteString]
BSL.toChunks (LazyByteString -> [ByteString])
-> (a -> LazyByteString) -> a -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> LazyByteString
forall a. Binary a => a -> LazyByteString
encode
sendMessage :: Serializable a
=> LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> a
-> IO ()
sendMessage :: forall a.
Serializable a =>
LocalNode
-> Identifier -> Identifier -> ImplicitReconnect -> a -> IO ()
sendMessage LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect =
LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> [ByteString]
-> IO ()
sendPayload LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect ([ByteString] -> IO ()) -> (a -> [ByteString]) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Message -> [ByteString]
messageToPayload (Message -> [ByteString]) -> (a -> Message) -> a -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Message
forall a. Serializable a => a -> Message
createMessage
setupConnBetween :: LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> IO (Maybe NT.Connection)
setupConnBetween :: LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> IO (Maybe Connection)
setupConnBetween LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect = do
Either (TransportError ConnectErrorCode) Connection
mConn <- EndPoint
-> EndPointAddress
-> Reliability
-> ConnectHints
-> IO (Either (TransportError ConnectErrorCode) Connection)
NT.connect (LocalNode -> EndPoint
localEndPoint LocalNode
node)
(NodeId -> EndPointAddress
nodeAddress (NodeId -> EndPointAddress)
-> (Identifier -> NodeId) -> Identifier -> EndPointAddress
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier -> NodeId
nodeOf (Identifier -> EndPointAddress) -> Identifier -> EndPointAddress
forall a b. (a -> b) -> a -> b
$ Identifier
to)
Reliability
NT.ReliableOrdered
ConnectHints
NT.defaultConnectHints
case Either (TransportError ConnectErrorCode) Connection
mConn of
Right Connection
conn -> do
Either (TransportError SendErrorCode) ()
didSend <- Connection
-> [ByteString] -> IO (Either (TransportError SendErrorCode) ())
NT.send Connection
conn (LazyByteString -> [ByteString]
BSL.toChunks (LazyByteString -> [ByteString])
-> (Identifier -> LazyByteString) -> Identifier -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier -> LazyByteString
forall a. Binary a => a -> LazyByteString
encode (Identifier -> [ByteString]) -> Identifier -> [ByteString]
forall a b. (a -> b) -> a -> b
$ Identifier
to)
case Either (TransportError SendErrorCode) ()
didSend of
Left TransportError SendErrorCode
_ ->
Maybe Connection -> IO (Maybe Connection)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Connection
forall a. Maybe a
Nothing
Right () -> do
LocalNode
-> (ValidLocalNodeState -> IO ValidLocalNodeState) -> IO ()
modifyValidLocalState_ LocalNode
node ((ValidLocalNodeState -> IO ValidLocalNodeState) -> IO ())
-> (ValidLocalNodeState -> IO ValidLocalNodeState) -> IO ()
forall a b. (a -> b) -> a -> b
$
ValidLocalNodeState -> IO ValidLocalNodeState
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ValidLocalNodeState -> IO ValidLocalNodeState)
-> (ValidLocalNodeState -> ValidLocalNodeState)
-> ValidLocalNodeState
-> IO ValidLocalNodeState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier
-> Identifier
-> Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
localConnectionBetween Identifier
from Identifier
to Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
-> Maybe (Connection, ImplicitReconnect)
-> ValidLocalNodeState
-> ValidLocalNodeState
forall r a. T r a -> a -> r -> r
^= (Connection, ImplicitReconnect)
-> Maybe (Connection, ImplicitReconnect)
forall a. a -> Maybe a
Just (Connection
conn, ImplicitReconnect
implicitReconnect))
Maybe Connection -> IO (Maybe Connection)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Connection -> IO (Maybe Connection))
-> Maybe Connection -> IO (Maybe Connection)
forall a b. (a -> b) -> a -> b
$ Connection -> Maybe Connection
forall a. a -> Maybe a
Just Connection
conn
Left TransportError ConnectErrorCode
_ ->
Maybe Connection -> IO (Maybe Connection)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Connection
forall a. Maybe a
Nothing
connBetween :: LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> IO (Maybe NT.Connection)
connBetween :: LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> IO (Maybe Connection)
connBetween LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect = do
Maybe (Connection, ImplicitReconnect)
mConn <- LocalNode
-> (ValidLocalNodeState
-> IO (Maybe (Connection, ImplicitReconnect)))
-> IO (Maybe (Connection, ImplicitReconnect))
forall r. LocalNode -> (ValidLocalNodeState -> IO r) -> IO r
withValidLocalState LocalNode
node ((ValidLocalNodeState
-> IO (Maybe (Connection, ImplicitReconnect)))
-> IO (Maybe (Connection, ImplicitReconnect)))
-> (ValidLocalNodeState
-> IO (Maybe (Connection, ImplicitReconnect)))
-> IO (Maybe (Connection, ImplicitReconnect))
forall a b. (a -> b) -> a -> b
$
Maybe (Connection, ImplicitReconnect)
-> IO (Maybe (Connection, ImplicitReconnect))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Connection, ImplicitReconnect)
-> IO (Maybe (Connection, ImplicitReconnect)))
-> (ValidLocalNodeState -> Maybe (Connection, ImplicitReconnect))
-> ValidLocalNodeState
-> IO (Maybe (Connection, ImplicitReconnect))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ValidLocalNodeState
-> Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
-> Maybe (Connection, ImplicitReconnect)
forall r a. r -> T r a -> a
^. Identifier
-> Identifier
-> Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
localConnectionBetween Identifier
from Identifier
to)
case Maybe (Connection, ImplicitReconnect)
mConn of
Just (Connection
conn, ImplicitReconnect
_) ->
Maybe Connection -> IO (Maybe Connection)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Connection -> IO (Maybe Connection))
-> Maybe Connection -> IO (Maybe Connection)
forall a b. (a -> b) -> a -> b
$ Connection -> Maybe Connection
forall a. a -> Maybe a
Just Connection
conn
Maybe (Connection, ImplicitReconnect)
Nothing ->
LocalNode
-> Identifier
-> Identifier
-> ImplicitReconnect
-> IO (Maybe Connection)
setupConnBetween LocalNode
node Identifier
from Identifier
to ImplicitReconnect
implicitReconnect
disconnect :: LocalNode -> Identifier -> Identifier -> IO ()
disconnect :: LocalNode -> Identifier -> Identifier -> IO ()
disconnect LocalNode
node Identifier
from Identifier
to = IO () -> IO ()
forall a. IO a -> IO a
mask_ (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Maybe (IO ())
mio <- LocalNode
-> (ValidLocalNodeState -> IO (ValidLocalNodeState, IO ()))
-> IO (Maybe (IO ()))
forall a.
LocalNode
-> (ValidLocalNodeState -> IO (ValidLocalNodeState, a))
-> IO (Maybe a)
modifyValidLocalState LocalNode
node ((ValidLocalNodeState -> IO (ValidLocalNodeState, IO ()))
-> IO (Maybe (IO ())))
-> (ValidLocalNodeState -> IO (ValidLocalNodeState, IO ()))
-> IO (Maybe (IO ()))
forall a b. (a -> b) -> a -> b
$ \ValidLocalNodeState
vst ->
case ValidLocalNodeState
vst ValidLocalNodeState
-> Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
-> Maybe (Connection, ImplicitReconnect)
forall r a. r -> T r a -> a
^. Identifier
-> Identifier
-> Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
localConnectionBetween Identifier
from Identifier
to of
Maybe (Connection, ImplicitReconnect)
Nothing ->
(ValidLocalNodeState, IO ()) -> IO (ValidLocalNodeState, IO ())
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ValidLocalNodeState
vst, () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ())
Just (Connection
conn, ImplicitReconnect
_) -> do
(ValidLocalNodeState, IO ()) -> IO (ValidLocalNodeState, IO ())
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ( Identifier
-> Identifier
-> Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
localConnectionBetween Identifier
from Identifier
to Accessor
ValidLocalNodeState (Maybe (Connection, ImplicitReconnect))
-> Maybe (Connection, ImplicitReconnect)
-> ValidLocalNodeState
-> ValidLocalNodeState
forall r a. T r a -> a -> r -> r
^= Maybe (Connection, ImplicitReconnect)
forall a. Maybe a
Nothing (ValidLocalNodeState -> ValidLocalNodeState)
-> ValidLocalNodeState -> ValidLocalNodeState
forall a b. (a -> b) -> a -> b
$ ValidLocalNodeState
vst
, Connection -> IO ()
NT.close Connection
conn
)
Maybe (IO ()) -> (IO () -> IO ThreadId) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe (IO ())
mio IO () -> IO ThreadId
forkIO
closeImplicitReconnections :: LocalNode -> Identifier -> IO ()
closeImplicitReconnections :: LocalNode -> Identifier -> IO ()
closeImplicitReconnections LocalNode
node Identifier
to = IO () -> IO ()
forall a. IO a -> IO a
mask_ (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Maybe [Connection]
mconns <- LocalNode
-> (ValidLocalNodeState -> IO (ValidLocalNodeState, [Connection]))
-> IO (Maybe [Connection])
forall a.
LocalNode
-> (ValidLocalNodeState -> IO (ValidLocalNodeState, a))
-> IO (Maybe a)
modifyValidLocalState LocalNode
node ((ValidLocalNodeState -> IO (ValidLocalNodeState, [Connection]))
-> IO (Maybe [Connection]))
-> (ValidLocalNodeState -> IO (ValidLocalNodeState, [Connection]))
-> IO (Maybe [Connection])
forall a b. (a -> b) -> a -> b
$ \ValidLocalNodeState
vst -> do
let shouldClose :: (a, Identifier) -> (a, ImplicitReconnect) -> Bool
shouldClose (a
_, Identifier
to') (a
_, ImplicitReconnect
WithImplicitReconnect) = Identifier
to Identifier -> Identifier -> Bool
`impliesDeathOf` Identifier
to'
shouldClose (a, Identifier)
_ (a, ImplicitReconnect)
_ = Bool
False
let (Map (Identifier, Identifier) (Connection, ImplicitReconnect)
affected, Map (Identifier, Identifier) (Connection, ImplicitReconnect)
unaffected) =
((Identifier, Identifier)
-> (Connection, ImplicitReconnect) -> Bool)
-> Map (Identifier, Identifier) (Connection, ImplicitReconnect)
-> (Map (Identifier, Identifier) (Connection, ImplicitReconnect),
Map (Identifier, Identifier) (Connection, ImplicitReconnect))
forall k a. (k -> a -> Bool) -> Map k a -> (Map k a, Map k a)
Map.partitionWithKey (Identifier, Identifier) -> (Connection, ImplicitReconnect) -> Bool
forall {a} {a}. (a, Identifier) -> (a, ImplicitReconnect) -> Bool
shouldClose (ValidLocalNodeState
vst ValidLocalNodeState
-> T ValidLocalNodeState
(Map (Identifier, Identifier) (Connection, ImplicitReconnect))
-> Map (Identifier, Identifier) (Connection, ImplicitReconnect)
forall r a. r -> T r a -> a
^. T ValidLocalNodeState
(Map (Identifier, Identifier) (Connection, ImplicitReconnect))
localConnections)
(ValidLocalNodeState, [Connection])
-> IO (ValidLocalNodeState, [Connection])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ( T ValidLocalNodeState
(Map (Identifier, Identifier) (Connection, ImplicitReconnect))
localConnections T ValidLocalNodeState
(Map (Identifier, Identifier) (Connection, ImplicitReconnect))
-> Map (Identifier, Identifier) (Connection, ImplicitReconnect)
-> ValidLocalNodeState
-> ValidLocalNodeState
forall r a. T r a -> a -> r -> r
^= Map (Identifier, Identifier) (Connection, ImplicitReconnect)
unaffected (ValidLocalNodeState -> ValidLocalNodeState)
-> ValidLocalNodeState -> ValidLocalNodeState
forall a b. (a -> b) -> a -> b
$ ValidLocalNodeState
vst
, ((Connection, ImplicitReconnect) -> Connection)
-> [(Connection, ImplicitReconnect)] -> [Connection]
forall a b. (a -> b) -> [a] -> [b]
map (Connection, ImplicitReconnect) -> Connection
forall a b. (a, b) -> a
fst ([(Connection, ImplicitReconnect)] -> [Connection])
-> [(Connection, ImplicitReconnect)] -> [Connection]
forall a b. (a -> b) -> a -> b
$ Map (Identifier, Identifier) (Connection, ImplicitReconnect)
-> [(Connection, ImplicitReconnect)]
forall k a. Map k a -> [a]
Map.elems Map (Identifier, Identifier) (Connection, ImplicitReconnect)
affected
)
Maybe [Connection] -> ([Connection] -> IO ThreadId) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Maybe [Connection]
mconns (([Connection] -> IO ThreadId) -> IO ())
-> ([Connection] -> IO ThreadId) -> IO ()
forall a b. (a -> b) -> a -> b
$ IO () -> IO ThreadId
forkIO (IO () -> IO ThreadId)
-> ([Connection] -> IO ()) -> [Connection] -> IO ThreadId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Connection -> IO ()) -> [Connection] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Connection -> IO ()
NT.close
impliesDeathOf :: Identifier
-> Identifier
-> Bool
NodeIdentifier NodeId
nid impliesDeathOf :: Identifier -> Identifier -> Bool
`impliesDeathOf` NodeIdentifier NodeId
nid' =
NodeId
nid' NodeId -> NodeId -> Bool
forall a. Eq a => a -> a -> Bool
== NodeId
nid
NodeIdentifier NodeId
nid `impliesDeathOf` ProcessIdentifier ProcessId
pid =
ProcessId -> NodeId
processNodeId ProcessId
pid NodeId -> NodeId -> Bool
forall a. Eq a => a -> a -> Bool
== NodeId
nid
NodeIdentifier NodeId
nid `impliesDeathOf` SendPortIdentifier SendPortId
cid =
ProcessId -> NodeId
processNodeId (SendPortId -> ProcessId
sendPortProcessId SendPortId
cid) NodeId -> NodeId -> Bool
forall a. Eq a => a -> a -> Bool
== NodeId
nid
ProcessIdentifier ProcessId
pid `impliesDeathOf` ProcessIdentifier ProcessId
pid' =
ProcessId
pid' ProcessId -> ProcessId -> Bool
forall a. Eq a => a -> a -> Bool
== ProcessId
pid
ProcessIdentifier ProcessId
pid `impliesDeathOf` SendPortIdentifier SendPortId
cid =
SendPortId -> ProcessId
sendPortProcessId SendPortId
cid ProcessId -> ProcessId -> Bool
forall a. Eq a => a -> a -> Bool
== ProcessId
pid
SendPortIdentifier SendPortId
cid `impliesDeathOf` SendPortIdentifier SendPortId
cid' =
SendPortId
cid' SendPortId -> SendPortId -> Bool
forall a. Eq a => a -> a -> Bool
== SendPortId
cid
Identifier
_ `impliesDeathOf` Identifier
_ =
Bool
False
sendCtrlMsg :: Maybe NodeId
-> ProcessSignal
-> Process ()
sendCtrlMsg :: Maybe NodeId -> ProcessSignal -> Process ()
sendCtrlMsg Maybe NodeId
mNid ProcessSignal
signal = do
LocalProcess
proc <- Process LocalProcess
forall r (m :: * -> *). MonadReader r m => m r
ask
let msg :: NCMsg
msg = NCMsg { ctrlMsgSender :: Identifier
ctrlMsgSender = ProcessId -> Identifier
ProcessIdentifier (LocalProcess -> ProcessId
processId LocalProcess
proc)
, ctrlMsgSignal :: ProcessSignal
ctrlMsgSignal = ProcessSignal
signal
}
case Maybe NodeId
mNid of
Maybe NodeId
Nothing -> do
IO () -> Process ()
forall a. IO a -> Process a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Process ()) -> IO () -> Process ()
forall a b. (a -> b) -> a -> b
$ Chan NCMsg -> NCMsg -> IO ()
forall a. Chan a -> a -> IO ()
writeChan (LocalNode -> Chan NCMsg
localCtrlChan (LocalProcess -> LocalNode
processNode LocalProcess
proc)) (NCMsg -> IO ()) -> NCMsg -> IO ()
forall a b. (a -> b) -> a -> b
$! NCMsg
msg
Just NodeId
nid ->
IO () -> Process ()
forall a. IO a -> Process a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Process ()) -> IO () -> Process ()
forall a b. (a -> b) -> a -> b
$ LocalNode
-> Identifier -> Identifier -> ImplicitReconnect -> NCMsg -> IO ()
forall a.
Binary a =>
LocalNode
-> Identifier -> Identifier -> ImplicitReconnect -> a -> IO ()
sendBinary (LocalProcess -> LocalNode
processNode LocalProcess
proc)
(NodeId -> Identifier
NodeIdentifier (ProcessId -> NodeId
processNodeId (ProcessId -> NodeId) -> ProcessId -> NodeId
forall a b. (a -> b) -> a -> b
$ LocalProcess -> ProcessId
processId LocalProcess
proc))
(NodeId -> Identifier
NodeIdentifier NodeId
nid)
ImplicitReconnect
WithImplicitReconnect
NCMsg
msg