@@ -1,10 +1,7 @@
1-- | We collect all types used internally in a single module to avoid using
1-- | We collect all types used internally in a single module to avoid using
2-- mutually recursive modules
2-- mutually recursive modules
3module Control.Distributed.Process.Internal.Types
3module Control.Distributed.Process.Internal.Types
4− ( -- * Global CH state
7− , -- * Node and process identifiers
4+ ( -- * Node and process identifiers
9 , LocalProcessId(..)
6 , LocalProcessId(..)
10 , ProcessId(..)
7 , ProcessId(..)
@@ -26,6 +23,11 @@ module Control.Distributed.Process.Internal.Types
26 , Static(..)
23 , Static(..)
27 , Closure(..)
24 , Closure(..)
28 , CallReply(..)
25 , CallReply(..)
29 -- * Messages
31 -- * Messages
30 , Message(..)
32 , Message(..)
31 -- * Node controller user-visible data types
33 -- * Node controller user-visible data types
@@ -63,12 +65,17 @@ module Control.Distributed.Process.Internal.Types
63import Data.Map (Map)
65import Data.Map (Map)
64import qualified Data.Map as Map (empty)
66import qualified Data.Map as Map (empty)
65import Data.Int (Int32)
67import Data.Int (Int32)
66−import Data.Typeable (Typeable)
68+import Data.Typeable (Typeable, TypeRep, TyCon, typeRepTyCon, typeOf)
67−import Data.Binary (Binary, encode, put, get, putWord8, getWord8)
69+import Data.Binary (Binary, encode, decode, put, get, putWord8, getWord8)
68import Data.ByteString.Lazy (ByteString)
70import Data.ByteString.Lazy (ByteString)
69−import Data.Accessor (Accessor, accessor)
71+import Data.Accessor (Accessor, accessor, (^=), (^.))
70import qualified Data.Accessor.Container as DAC (mapMaybe)
72import 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
72import qualified Data.ByteString as BSS (ByteString, concat)
79import qualified Data.ByteString as BSS (ByteString, concat)
73import Control.Category ((>>>))
80import Control.Category ((>>>))
74import Control.Exception (Exception)
81import Control.Exception (Exception)
@@ -81,26 +88,23 @@ import Control.Applicative (Applicative, (<$>), (<*>))
81import Control.Monad.Reader (MonadReader(..), ReaderT, runReaderT)
88import Control.Monad.Reader (MonadReader(..), ReaderT, runReaderT)
82import Control.Monad.IO.Class (MonadIO)
89import Control.Monad.IO.Class (MonadIO)
83import Control.Monad.State (MonadState, StateT, evalStateT)
90import Control.Monad.State (MonadState, StateT, evalStateT)
84−import Control.Distributed.Process.Serializable ( Fingerprint
91+import Control.Distributed.Process.Serializable
85− , Serializable
93+ , Serializable
86− , encodeFingerprint
94+ , encodeFingerprint
87− , decodeFingerprint
95+ , decodeFingerprint
88− , fingerprint
96+ , fingerprint
89− , sizeOfFingerprint
97+ , sizeOfFingerprint
91import Control.Distributed.Process.Internal.CQueue (CQueue)
99import Control.Distributed.Process.Internal.CQueue (CQueue)
92−import Control.Distributed.Process.Internal.Dynamic (Dynamic)
100+import Control.Distributed.Process.Internal.Dynamic
94−--------------------------------------------------------------------------------
102+ , toDyn
95−-- Global state --
103+ , fromDynamic
96−--------------------------------------------------------------------------------
104+ , dynTypeRep
98−-- | Used to fake 'static' (see paper)
106+ , dynBind
99−type RemoteTable = Map String Dynamic
107+ )
101−-- | Initial (empty) remote-call meta data
102−initRemoteTable :: RemoteTable
103−initRemoteTable = Map.empty
105--------------------------------------------------------------------------------
109--------------------------------------------------------------------------------
106-- Node and process identifiers --
110-- Node and process identifiers --
@@ -231,6 +235,45 @@ data Closure a = Closure (Static (ByteString -> a)) ByteString
231newtype CallReply a = CallReply a
235newtype CallReply a = CallReply a
232 deriving (Typeable, Binary)
236 deriving (Typeable, Binary)
238+-- | Used to fake 'static' (see paper)
239+data RemoteTable = RemoteTable {
240+ _remoteTableLabels :: Map String Dynamic
241+ , _remoteTableSenders :: Map TypeRep Dynamic
244+-- | Initial (empty) remote-call meta data
245+initRemoteTable :: RemoteTable
246+initRemoteTable = RemoteTable Map.empty Map.empty
248+registerLabel :: String -> Dynamic -> RemoteTable -> RemoteTable
249+registerLabel label dyn = remoteTableLabel label ^= Just dyn
251+registerSender :: TypeRep -> Dynamic -> RemoteTable -> RemoteTable
252+registerSender typ dyn = remoteTableSender typ ^= Just dyn
254+resolveClosure :: RemoteTable -> String -> Maybe Dynamic
255+resolveClosure rtable "$call" = Just (toDyn aux)
257+ -- TODO: error handling
258+ aux :: ByteString -> Process ()
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
269+resolveClosure rtable label = rtable ^. remoteTableLabel label
271+tyConProcess :: TyCon
272+tyConProcess = typeRepTyCon (typeOf (undefined :: Process ()))
274+bindProcess :: Process a -> (a -> Process b) -> Process b
234--------------------------------------------------------------------------------
277--------------------------------------------------------------------------------
235-- Messages --
278-- Messages --
236--------------------------------------------------------------------------------
279--------------------------------------------------------------------------------
@@ -449,6 +492,18 @@ typedChannels = accessor _typedChannels (\cs st -> st { _typedChannels = cs })
449typedChannelWithId :: LocalChannelId -> Accessor LocalProcessState (Maybe TypedChannel)
492typedChannelWithId :: LocalChannelId -> Accessor LocalProcessState (Maybe TypedChannel)
450typedChannelWithId cid = typedChannels >>> DAC.mapMaybe cid
493typedChannelWithId cid = typedChannels >>> DAC.mapMaybe cid
495+remoteTableLabels :: Accessor RemoteTable (Map String Dynamic)
496+remoteTableLabels = accessor _remoteTableLabels (\ls tbl -> tbl { _remoteTableLabels = ls })
498+remoteTableSenders :: Accessor RemoteTable (Map TypeRep Dynamic)
499+remoteTableSenders = accessor _remoteTableSenders (\es tbl -> tbl { _remoteTableSenders = es })
501+remoteTableLabel :: String -> Accessor RemoteTable (Maybe Dynamic)
502+remoteTableLabel label = remoteTableLabels >>> DAC.mapMaybe label
504+remoteTableSender :: TypeRep -> Accessor RemoteTable (Maybe Dynamic)
505+remoteTableSender typ = remoteTableSenders >>> DAC.mapMaybe typ
452--------------------------------------------------------------------------------
507--------------------------------------------------------------------------------
453-- MessageT monad --
508-- MessageT monad --
454--------------------------------------------------------------------------------
509--------------------------------------------------------------------------------