@@ -1,10 +1,7 @@
11-- | We collect all types used internally in a single module to avoid using
22-- mutually recursive modules
33module Control.Distributed.Process.Internal.Types
4− ( -- * Global CH state
5− RemoteTable
6− , initRemoteTable
7− , -- * Node and process identifiers
4+ ( -- * Node and process identifiers
85 NodeId(..)
96 , LocalProcessId(..)
107 , ProcessId(..)
@@ -26,6 +23,11 @@ module Control.Distributed.Process.Internal.Types
2623 , Static(..)
2724 , Closure(..)
2825 , CallReply(..)
26+ , RemoteTable
27+ , initRemoteTable
28+ , registerLabel
29+ , registerSender
30+ , resolveClosure
2931 -- * Messages
3032 , Message(..)
3133 -- * Node controller user-visible data types
@@ -63,12 +65,17 @@ module Control.Distributed.Process.Internal.Types
6365import Data.Map (Map)
6466import qualified Data.Map as Map (empty)
6567import Data.Int (Int32)
66−import Data.Typeable (Typeable)
67−import Data.Binary (Binary, encode, put, get, putWord8, getWord8)
68+import Data.Typeable (Typeable, TypeRep, TyCon, typeRepTyCon, typeOf)
69+import Data.Binary (Binary, encode, decode, put, get, putWord8, getWord8)
6870import Data.ByteString.Lazy (ByteString)
69−import Data.Accessor (Accessor, accessor)
71+import Data.Accessor (Accessor, accessor, (^=), (^.))
7072import qualified Data.Accessor.Container as DAC (mapMaybe)
71−import qualified Data.ByteString.Lazy as BSL (ByteString, toChunks, fromChunks, splitAt)
73+import qualified Data.ByteString.Lazy as BSL
74+ ( ByteString
75+ , toChunks
76+ , fromChunks
77+ , splitAt
78+ )
7279import qualified Data.ByteString as BSS (ByteString, concat)
7380import Control.Category ((>>>))
7481import Control.Exception (Exception)
@@ -81,26 +88,23 @@ import Control.Applicative (Applicative, (<$>), (<*>))
8188import Control.Monad.Reader (MonadReader(..), ReaderT, runReaderT)
8289import Control.Monad.IO.Class (MonadIO)
8390import Control.Monad.State (MonadState, StateT, evalStateT)
84−import Control.Distributed.Process.Serializable ( Fingerprint
85− , Serializable
86− , encodeFingerprint
87− , decodeFingerprint
88− , fingerprint
89− , sizeOfFingerprint
90− )
91+import Control.Distributed.Process.Serializable
92+ ( Fingerprint
93+ , Serializable
94+ , encodeFingerprint
95+ , decodeFingerprint
96+ , fingerprint
97+ , sizeOfFingerprint
98+ )
9199import Control.Distributed.Process.Internal.CQueue (CQueue)
92−import Control.Distributed.Process.Internal.Dynamic (Dynamic)
93−
94−--------------------------------------------------------------------------------
95−-- Global state --
96−--------------------------------------------------------------------------------
97−
98−-- | Used to fake 'static' (see paper)
99−type RemoteTable = Map String Dynamic
100−
101−-- | Initial (empty) remote-call meta data
102−initRemoteTable :: RemoteTable
103−initRemoteTable = Map.empty
100+import Control.Distributed.Process.Internal.Dynamic
101+ ( Dynamic
102+ , toDyn
103+ , fromDynamic
104+ , dynTypeRep
105+ , dynApp
106+ , dynBind
107+ )
104108
105109--------------------------------------------------------------------------------
106110-- Node and process identifiers --
@@ -231,6 +235,45 @@ data Closure a = Closure (Static (ByteString -> a)) ByteString
231235newtype CallReply a = CallReply a
232236 deriving (Typeable, Binary)
233237
238+-- | Used to fake 'static' (see paper)
239+data RemoteTable = RemoteTable {
240+ _remoteTableLabels :: Map String Dynamic
241+ , _remoteTableSenders :: Map TypeRep Dynamic
242+ }
243+
244+-- | Initial (empty) remote-call meta data
245+initRemoteTable :: RemoteTable
246+initRemoteTable = RemoteTable Map.empty Map.empty
247+
248+registerLabel :: String -> Dynamic -> RemoteTable -> RemoteTable
249+registerLabel label dyn = remoteTableLabel label ^= Just dyn
250+
251+registerSender :: TypeRep -> Dynamic -> RemoteTable -> RemoteTable
252+registerSender typ dyn = remoteTableSender typ ^= Just dyn
253+
254+resolveClosure :: RemoteTable -> String -> Maybe Dynamic
255+resolveClosure rtable "$call" = Just (toDyn aux)
256+ where
257+ -- TODO: error handling
258+ aux :: ByteString -> Process ()
259+ aux env = do
260+ let (label, env', pid) = decode env :: (String, ByteString, ProcessId)
261+ Just proc = resolveClosure rtable label
262+ proc' = dynApp proc (toDyn env')
263+ Just enc = rtable ^. remoteTableSender (dynTypeRep proc')
264+ enc' = dynApp enc (toDyn pid)
265+ Just bound = dynBind tyConProcess bindProcess proc' enc'
266+ Just proc'' = fromDynamic bound
267+ proc''
268+
269+resolveClosure rtable label = rtable ^. remoteTableLabel label
270+
271+tyConProcess :: TyCon
272+tyConProcess = typeRepTyCon (typeOf (undefined :: Process ()))
273+
274+bindProcess :: Process a -> (a -> Process b) -> Process b
275+bindProcess = (>>=)
276+
234277--------------------------------------------------------------------------------
235278-- Messages --
236279--------------------------------------------------------------------------------
@@ -449,6 +492,18 @@ typedChannels = accessor _typedChannels (\cs st -> st { _typedChannels = cs })
449492typedChannelWithId :: LocalChannelId -> Accessor LocalProcessState (Maybe TypedChannel)
450493typedChannelWithId cid = typedChannels >>> DAC.mapMaybe cid
451494
495+remoteTableLabels :: Accessor RemoteTable (Map String Dynamic)
496+remoteTableLabels = accessor _remoteTableLabels (\ls tbl -> tbl { _remoteTableLabels = ls })
497+
498+remoteTableSenders :: Accessor RemoteTable (Map TypeRep Dynamic)
499+remoteTableSenders = accessor _remoteTableSenders (\es tbl -> tbl { _remoteTableSenders = es })
500+
501+remoteTableLabel :: String -> Accessor RemoteTable (Maybe Dynamic)
502+remoteTableLabel label = remoteTableLabels >>> DAC.mapMaybe label
503+
504+remoteTableSender :: TypeRep -> Accessor RemoteTable (Maybe Dynamic)
505+remoteTableSender typ = remoteTableSenders >>> DAC.mapMaybe typ
506+
452507--------------------------------------------------------------------------------
453508-- MessageT monad --
454509--------------------------------------------------------------------------------