@@ -33,6 +33,9 @@ module Control.Distributed.Process.Internal.Types
33 , RuntimeSerializableSupport(..)
33 , RuntimeSerializableSupport(..)
34 -- * Messages
34 -- * Messages
35 , Message(..)
35 , Message(..)
36 -- * Node controller user-visible data types
39 -- * Node controller user-visible data types
37 , MonitorRef(..)
40 , MonitorRef(..)
38 , ProcessMonitorNotification(..)
41 , ProcessMonitorNotification(..)
@@ -48,6 +51,7 @@ module Control.Distributed.Process.Internal.Types
48 , DidUnlinkPort(..)
51 , DidUnlinkPort(..)
49 , SpawnRef(..)
52 , SpawnRef(..)
50 , DidSpawn(..)
53 , DidSpawn(..)
51 -- * Node controller internal data types
55 -- * Node controller internal data types
52 , NCMsg(..)
56 , NCMsg(..)
53 , ProcessSignal(..)
57 , ProcessSignal(..)
@@ -73,11 +77,16 @@ module Control.Distributed.Process.Internal.Types
73import Data.Map (Map)
77import Data.Map (Map)
74import Data.Int (Int32)
78import Data.Int (Int32)
75import Data.Typeable (Typeable, TypeRep)
79import Data.Typeable (Typeable, TypeRep)
76−import Data.Binary (Binary(put, get), putWord8, getWord8)
80+import Data.Binary (Binary(put, get), putWord8, getWord8, encode)
81+import qualified Data.ByteString as BSS (ByteString, concat)
77−import Data.ByteString.Lazy (ByteString)
82+import qualified Data.ByteString.Lazy as BSL
78import Data.Accessor (Accessor, accessor)
88import Data.Accessor (Accessor, accessor)
79import qualified Data.Accessor.Container as DAC (mapMaybe)
89import qualified Data.Accessor.Container as DAC (mapMaybe)
80−import qualified Data.ByteString.Lazy as BSL (ByteString)
81import Control.Category ((>>>))
90import Control.Category ((>>>))
82import Control.Exception (Exception)
91import Control.Exception (Exception)
83import Control.Concurrent (ThreadId)
92import Control.Concurrent (ThreadId)
@@ -90,7 +99,14 @@ import Control.Monad.Reader (MonadReader(..), ReaderT)
90import Control.Monad.IO.Class (MonadIO)
99import Control.Monad.IO.Class (MonadIO)
91import Control.Monad.State (MonadState, StateT)
100import Control.Monad.State (MonadState, StateT)
92import qualified Control.Monad.Trans.Class as Trans (lift)
101import qualified Control.Monad.Trans.Class as Trans (lift)
93−import Control.Distributed.Process.Serializable (Fingerprint, Serializable)
102+import Control.Distributed.Process.Serializable
94import Control.Distributed.Process.Internal.CQueue (CQueue)
110import Control.Distributed.Process.Internal.CQueue (CQueue)
95import Control.Distributed.Process.Internal.Dynamic (Dynamic)
111import Control.Distributed.Process.Internal.Dynamic (Dynamic)
@@ -255,7 +271,7 @@ newtype Static a = Static StaticLabel
255 deriving (Typeable, Show)
271 deriving (Typeable, Show)
257-- | A closure is a static value and an encoded environment
273-- | 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
259 deriving (Typeable, Show)
275 deriving (Typeable, Show)
261-- | Used to fake 'static' (see paper)
277-- | Used to fake 'static' (see paper)
@@ -294,6 +310,25 @@ data Message = Message
294 , messageEncoding :: BSL.ByteString
310 , messageEncoding :: BSL.ByteString
313+instance Show Message where
314+ show = show . messageEncoding
316+-- | Turn any serialiable term into a message
317+createMessage :: Serializable a => a -> Message
318+createMessage a = Message (fingerprint a) (encode a)
320+-- | Serialize a message
321+messageToPayload :: Message -> [BSS.ByteString]
322+messageToPayload (Message fp enc) = encodeFingerprint fp : BSL.toChunks enc
324+-- | Deserialize a message
325+payloadToMessage :: [BSS.ByteString] -> Message
326+payloadToMessage payload = Message fp msg
328+ (encFp, msg) = BSL.splitAt (fromIntegral sizeOfFingerprint)
329+ $ BSL.fromChunks payload
330+ fp = decodeFingerprint . BSS.concat . BSL.toChunks $ encFp
297--------------------------------------------------------------------------------
332--------------------------------------------------------------------------------
298-- Node controller user-visible data types --
333-- Node controller user-visible data types --
299--------------------------------------------------------------------------------
334--------------------------------------------------------------------------------
@@ -376,10 +411,14 @@ newtype DidUnlinkPort = DidUnlinkPort SendPortId
376newtype SpawnRef = SpawnRef Int32
411newtype SpawnRef = SpawnRef Int32
377 deriving (Show, Binary, Typeable, Eq)
412 deriving (Show, Binary, Typeable, Eq)
379−-- | (Asynchronius) reply from spawn
414+-- | (Asynchronius) reply from 'spawn'
380data DidSpawn = DidSpawn SpawnRef ProcessId
415data DidSpawn = DidSpawn SpawnRef ProcessId
381 deriving (Show, Typeable)
416 deriving (Show, Typeable)
418+-- | (Asynchronous) reply from 'whereis'
419+data WhereIsReply = WhereIsReply String (Maybe ProcessId)
420+ deriving (Show, Typeable)
383--------------------------------------------------------------------------------
422--------------------------------------------------------------------------------
384-- Node controller internal data types --
423-- Node controller internal data types --
385--------------------------------------------------------------------------------
424--------------------------------------------------------------------------------
@@ -399,6 +438,9 @@ data ProcessSignal =
399 | Unmonitor MonitorRef
438 | Unmonitor MonitorRef
400 | Died Identifier DiedReason
439 | Died Identifier DiedReason
401 | Spawn (Closure (Process ())) SpawnRef
440 | Spawn (Closure (Process ())) SpawnRef
442+ | Register String (Maybe ProcessId) -- Nothing to unregister
443+ | NamedSend String Message
402 deriving Show
444 deriving Show
404--------------------------------------------------------------------------------
446--------------------------------------------------------------------------------
@@ -434,12 +476,15 @@ instance Binary MonitorRef where
434 get = MonitorRef <$> get <*> get
476 get = MonitorRef <$> get <*> get
436instance Binary ProcessSignal where
478instance Binary ProcessSignal where
437− put (Link pid) = putWord8 0 >> put pid
479+ put (Link pid) = putWord8 0 >> put pid
438− put (Unlink pid) = putWord8 1 >> put pid
480+ put (Unlink pid) = putWord8 1 >> put pid
439− put (Monitor ref) = putWord8 2 >> put ref
481+ put (Monitor ref) = putWord8 2 >> put ref
440− put (Unmonitor ref) = putWord8 3 >> put ref
482+ put (Unmonitor ref) = putWord8 3 >> put ref
441− put (Died who reason) = putWord8 4 >> put who >> put reason
483+ put (Died who reason) = putWord8 4 >> put who >> put reason
442− put (Spawn proc ref) = putWord8 5 >> put proc >> put ref
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)
444 header <- getWord8
489 header <- getWord8
445 case header of
490 case header of
@@ -449,6 +494,9 @@ instance Binary ProcessSignal where
449 3 -> Unmonitor <$> get
494 3 -> Unmonitor <$> get
450 4 -> Died <$> get <*> get
495 4 -> Died <$> get <*> get
451 5 -> Spawn <$> get <*> get
496 5 -> Spawn <$> get <*> get
497+ 6 -> WhereIs <$> get
498+ 7 -> Register <$> get <*> get
499+ 8 -> NamedSend <$> get <*> (payloadToMessage <$> get)
452 _ -> fail "ProcessSignal.get: invalid"
500 _ -> fail "ProcessSignal.get: invalid"
454instance Binary DiedReason where
502instance Binary DiedReason where
@@ -529,7 +577,9 @@ instance Binary StaticLabel where
529 15 -> return CpApply
577 15 -> return CpApply
530 _ -> fail "StaticLabel.get: invalid"
578 _ -> fail "StaticLabel.get: invalid"
532−
580+instance Binary WhereIsReply where
581+ put (WhereIsReply label mPid) = put label >> put mPid
582+ get = WhereIsReply <$> get <*> get
534--------------------------------------------------------------------------------
584--------------------------------------------------------------------------------
535-- Accessors --
585-- Accessors --