@@ -33,6 +33,9 @@ module Control.Distributed.Process.Internal.Types
3333 , RuntimeSerializableSupport(..)
3434 -- * Messages
3535 , Message(..)
36+ , createMessage
37+ , messageToPayload
38+ , payloadToMessage
3639 -- * Node controller user-visible data types
3740 , MonitorRef(..)
3841 , ProcessMonitorNotification(..)
@@ -48,6 +51,7 @@ module Control.Distributed.Process.Internal.Types
4851 , DidUnlinkPort(..)
4952 , SpawnRef(..)
5053 , DidSpawn(..)
54+ , WhereIsReply(..)
5155 -- * Node controller internal data types
5256 , NCMsg(..)
5357 , ProcessSignal(..)
@@ -73,11 +77,16 @@ module Control.Distributed.Process.Internal.Types
7377import Data.Map (Map)
7478import Data.Int (Int32)
7579import Data.Typeable (Typeable, TypeRep)
76−import Data.Binary (Binary(put, get), putWord8, getWord8)
77−import Data.ByteString.Lazy (ByteString)
80+import Data.Binary (Binary(put, get), putWord8, getWord8, encode)
81+import qualified Data.ByteString as BSS (ByteString, concat)
82+import qualified Data.ByteString.Lazy as BSL
83+ ( ByteString
84+ , toChunks
85+ , splitAt
86+ , fromChunks
87+ )
7888import Data.Accessor (Accessor, accessor)
7989import qualified Data.Accessor.Container as DAC (mapMaybe)
80−import qualified Data.ByteString.Lazy as BSL (ByteString)
8190import Control.Category ((>>>))
8291import Control.Exception (Exception)
8392import Control.Concurrent (ThreadId)
@@ -90,7 +99,14 @@ import Control.Monad.Reader (MonadReader(..), ReaderT)
9099import Control.Monad.IO.Class (MonadIO)
91100import Control.Monad.State (MonadState, StateT)
92101import qualified Control.Monad.Trans.Class as Trans (lift)
93−import Control.Distributed.Process.Serializable (Fingerprint, Serializable)
102+import Control.Distributed.Process.Serializable
103+ ( Fingerprint
104+ , Serializable
105+ , fingerprint
106+ , encodeFingerprint
107+ , sizeOfFingerprint
108+ , decodeFingerprint
109+ )
94110import Control.Distributed.Process.Internal.CQueue (CQueue)
95111import Control.Distributed.Process.Internal.Dynamic (Dynamic)
96112
@@ -255,7 +271,7 @@ newtype Static a = Static StaticLabel
255271 deriving (Typeable, Show)
256272
257273-- | A closure is a static value and an encoded environment
258−data Closure a = Closure (Static (ByteString -> a)) ByteString
274+data Closure a = Closure (Static (BSL.ByteString -> a)) BSL.ByteString
259275 deriving (Typeable, Show)
260276
261277-- | Used to fake 'static' (see paper)
@@ -294,6 +310,25 @@ data Message = Message
294310 , messageEncoding :: BSL.ByteString
295311 }
296312
313+instance Show Message where
314+ show = show . messageEncoding
315+
316+-- | Turn any serialiable term into a message
317+createMessage :: Serializable a => a -> Message
318+createMessage a = Message (fingerprint a) (encode a)
319+
320+-- | Serialize a message
321+messageToPayload :: Message -> [BSS.ByteString]
322+messageToPayload (Message fp enc) = encodeFingerprint fp : BSL.toChunks enc
323+
324+-- | Deserialize a message
325+payloadToMessage :: [BSS.ByteString] -> Message
326+payloadToMessage payload = Message fp msg
327+ where
328+ (encFp, msg) = BSL.splitAt (fromIntegral sizeOfFingerprint)
329+ $ BSL.fromChunks payload
330+ fp = decodeFingerprint . BSS.concat . BSL.toChunks $ encFp
331+
297332--------------------------------------------------------------------------------
298333-- Node controller user-visible data types --
299334--------------------------------------------------------------------------------
@@ -376,10 +411,14 @@ newtype DidUnlinkPort = DidUnlinkPort SendPortId
376411newtype SpawnRef = SpawnRef Int32
377412 deriving (Show, Binary, Typeable, Eq)
378413
379−-- | (Asynchronius) reply from spawn
414+-- | (Asynchronius) reply from 'spawn'
380415data DidSpawn = DidSpawn SpawnRef ProcessId
381416 deriving (Show, Typeable)
382417
418+-- | (Asynchronous) reply from 'whereis'
419+data WhereIsReply = WhereIsReply String (Maybe ProcessId)
420+ deriving (Show, Typeable)
421+
383422--------------------------------------------------------------------------------
384423-- Node controller internal data types --
385424--------------------------------------------------------------------------------
@@ -399,6 +438,9 @@ data ProcessSignal =
399438 | Unmonitor MonitorRef
400439 | Died Identifier DiedReason
401440 | Spawn (Closure (Process ())) SpawnRef
441+ | WhereIs String
442+ | Register String (Maybe ProcessId) -- Nothing to unregister
443+ | NamedSend String Message
402444 deriving Show
403445
404446--------------------------------------------------------------------------------
@@ -434,12 +476,15 @@ instance Binary MonitorRef where
434476 get = MonitorRef <$> get <*> get
435477
436478instance Binary ProcessSignal where
437− put (Link pid) = putWord8 0 >> put pid
438− put (Unlink pid) = putWord8 1 >> put pid
439− put (Monitor ref) = putWord8 2 >> put ref
440− put (Unmonitor ref) = putWord8 3 >> put ref
441− put (Died who reason) = putWord8 4 >> put who >> put reason
442− put (Spawn proc ref) = putWord8 5 >> put proc >> put ref
479+ put (Link pid) = putWord8 0 >> put pid
480+ put (Unlink pid) = putWord8 1 >> put pid
481+ put (Monitor ref) = putWord8 2 >> put ref
482+ put (Unmonitor ref) = putWord8 3 >> put ref
483+ put (Died who reason) = putWord8 4 >> put who >> put reason
484+ put (Spawn proc ref) = putWord8 5 >> put proc >> put ref
485+ put (WhereIs label) = putWord8 6 >> put label
486+ put (Register label pid) = putWord8 7 >> put label >> put pid
487+ put (NamedSend label msg) = putWord8 8 >> put label >> put (messageToPayload msg)
443488 get = do
444489 header <- getWord8
445490 case header of
@@ -449,6 +494,9 @@ instance Binary ProcessSignal where
449494 3 -> Unmonitor <$> get
450495 4 -> Died <$> get <*> get
451496 5 -> Spawn <$> get <*> get
497+ 6 -> WhereIs <$> get
498+ 7 -> Register <$> get <*> get
499+ 8 -> NamedSend <$> get <*> (payloadToMessage <$> get)
452500 _ -> fail "ProcessSignal.get: invalid"
453501
454502instance Binary DiedReason where
@@ -529,7 +577,9 @@ instance Binary StaticLabel where
529577 15 -> return CpApply
530578 _ -> fail "StaticLabel.get: invalid"
531579
532−
580+instance Binary WhereIsReply where
581+ put (WhereIsReply label mPid) = put label >> put mPid
582+ get = WhereIsReply <$> get <*> get
533583
534584--------------------------------------------------------------------------------
535585-- Accessors --