git.iko.soy/distributed-process
on master help sign in
Add support for 'returnClosure'
commit38091bb1866d98a41bfc71d8e13bcd8336dcfa5e authorEdsko de Vries <edsko@edsko.net> dateThu 28 Jun 2012, 15:05 (14 years ago) parent7f7e274
9 files changed+158−117
distributed-process/distributed-process.cabal+3−3 distributed-process/src/Control/Distributed/Process.hs+11−10 distributed-process/src/Control/Distributed/Process/Closure.hs+21−1 distributed-process/src/Control/Distributed/Process/Internal/Closure.hs+12−17 distributed-process/src/Control/Distributed/Process/Internal/Closure/BuiltIn.hs+17 distributed-process/src/Control/Distributed/Process/Internal/Closure/BuiltIn.hs-boot+4−1 distributed-process/src/Control/Distributed/Process/Internal/Closure/TH.hs+26−37 distributed-process/src/Control/Distributed/Process/Internal/Types.hs+57−41 distributed-process/tests/TestClosure.hs+7−7
distributed-process/distributed-process.cabal+3−3
@@ -26,7 +26,7 @@ Library
2626 Control.Distributed.Process.Serializable,
2727 Control.Distributed.Process.Closure,
2828 Control.Distributed.Process.Node
29− Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes
29+ Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes, GADTs
3030 ghc-options: -Wall
3131 HS-Source-Dirs: src
3232
@@ -46,7 +46,7 @@ Test-Suite TestCH
4646 stm,
4747 ghc-prim,
4848 network-transport >= 0.1
49− Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes
49+ Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes, GADTs
5050 ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -fno-warn-unused-do-bind
5151 HS-Source-Dirs: tests src
5252
@@ -67,6 +67,6 @@ Test-Suite TestClosure
6767 template-haskell,
6868 stm,
6969 network-transport >= 0.1
70− Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes
70+ Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, ExistentialQuantification, RankNTypes, GADTs
7171 ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -fno-warn-unused-do-bind
7272 HS-Source-Dirs: tests src
distributed-process/src/Control/Distributed/Process.hs+11−10
@@ -62,7 +62,7 @@ module Control.Distributed.Process
6262 ) where
6363
6464import Prelude hiding (catch)
65−import Data.Binary (decode, encode)
65+import Data.Binary (decode)
6666import Data.Typeable (Typeable, typeOf)
6767import Control.Monad.Reader (ask)
6868import Control.Monad.IO.Class (MonadIO, liftIO)
@@ -92,7 +92,6 @@ import Control.Distributed.Process.Internal.Types
9292 , LocalProcess(..)
9393 , Process(..)
9494 , Closure(..)
95− , StaticLabel(Call)
9695 , Static(..)
9796 , Message(..)
9897 , MonitorRef(..)
@@ -108,7 +107,6 @@ import Control.Distributed.Process.Internal.Types
108107 , monitorCounter
109108 , spawnCounter
110109 , Closure(..)
111− , CallReply(..)
112110 , SendPort(..)
113111 , ReceivePort(..)
114112 , channelCounter
@@ -117,6 +115,7 @@ import Control.Distributed.Process.Internal.Types
117115 , ChannelId(..)
118116 , Identifier(..)
119117 , procMsg
118+ , SerializableDict(..)
120119 )
121120import Control.Distributed.Process.Internal.MessageT
122121 ( sendMessage
@@ -126,8 +125,11 @@ import Control.Distributed.Process.Internal.MessageT
126125import Control.Distributed.Process.Internal.Dynamic (fromDyn, dynTypeRep)
127126import Control.Distributed.Process.Internal.Closure (resolveClosure)
128127import Control.Distributed.Process.Internal.Node (runLocalProcess)
129−import {-# SOURCE #-} Control.Distributed.Process.Internal.Closure.BuiltIn (linkClosure)
130−import Control.Distributed.Process.Internal.Closure.Combinators (cpSeq)
128+import {-# SOURCE #-} Control.Distributed.Process.Internal.Closure.BuiltIn
129+ ( linkClosure
130+ , sendClosure
131+ )
132+import Control.Distributed.Process.Internal.Closure.Combinators (cpSeq, cpBind)
131133
132134-- INTERNAL NOTES
133135--
@@ -318,12 +320,11 @@ spawn nid proc = do
318320 ]
319321
320322-- | Run a process remotely and wait for it to reply
321−call :: Serializable a => NodeId -> Closure (Process a) -> Process a
322−call nid (Closure (Static label) env) = do
323+call :: SerializableDict a -> NodeId -> Closure (Process a) -> Process a
324+call sdict@(SerializableDict _) nid proc = do
323325 us <- getSelfPid
324− spawn nid (Closure (Static Call) (encode (label, env, us)))
325− CallReply a <- expect
326− return a
326+ spawn nid (proc `cpBind` sendClosure sdict us)
327+ expect
327328
328329-- | Thrown by 'terminate'
329330data ProcessTerminationException = ProcessTerminationException
distributed-process/src/Control/Distributed/Process/Closure.hs+21−1
@@ -56,12 +56,27 @@
5656-- > $ initRemoteTable
5757--
5858-- See Section 6, /Faking It/, of /Towards Haskell in the Cloud/ for more info.
59+--
60+-- [Serializable Dictionaries]
61+--
62+-- Some functions (such as 'sendClosure' or 'returnClosure') require an
63+-- explicit (reified) serializable dictionary. To create such a dictionary do
64+--
65+-- > serializableDictInt :: SerializableDict Int
66+-- > serializableDictInt = SerializableDict "serializableDictInt"
67+--
68+-- and then pass @'serialiableDictInt@ to 'remotable'. This will fail if the
69+-- type is not serializable. Make sure that the string argument to provide
70+-- in the definition of your dictionary matches the function name.
5971module Control.Distributed.Process.Closure
6072 ( -- * User-defined closures
6173 remotable
6274 , mkClosure
75+ , SerializableDict(..)
6376 -- * Built-in closures
6477 , linkClosure
78+ , sendClosure
79+ , returnClosure
6580 -- * Generic closure combinators
6681 , closureApply
6782 , closureConst
@@ -90,8 +105,13 @@ module Control.Distributed.Process.Closure
90105 , cpSeq
91106 ) where
92107
108+import Control.Distributed.Process.Internal.Types (SerializableDict(..))
93109import Control.Distributed.Process.Internal.Closure.TH (remotable, mkClosure)
94−import Control.Distributed.Process.Internal.Closure.BuiltIn (linkClosure)
110+import Control.Distributed.Process.Internal.Closure.BuiltIn
111+ ( linkClosure
112+ , sendClosure
113+ , returnClosure
114+ )
95115import Control.Distributed.Process.Internal.Closure.Combinators
96116 ( -- Generic combinators
97117 closureApply
distributed-process/src/Control/Distributed/Process/Internal/Closure.hs+12−17
@@ -7,25 +7,23 @@ module Control.Distributed.Process.Internal.Closure
77
88import qualified Data.Map as Map (empty)
99import Data.Accessor ((^.))
10−import Data.Typeable (TyCon, typeRepTyCon, typeOf)
1110import Data.ByteString.Lazy (ByteString)
1211import Data.Binary (decode)
1312import Control.Distributed.Process.Internal.Types
1413 ( RemoteTable(RemoteTable)
1514 , remoteTableLabel
16− , remoteTableSender
15+ , remoteTableDict
1716 , StaticLabel(..)
1817 , ProcessId
1918 , Process
2019 , Closure(Closure)
2120 , Static(Static)
21+ , RuntimeSerializableSupport(..)
2222 )
2323import Control.Distributed.Process.Internal.Dynamic
2424 ( Dynamic(Dynamic)
25− , dynTypeRep
2625 , toDyn
2726 , dynApp
28− , dynBind
2927 , dynApply
3028 , unsafeCoerce#
3129 )
@@ -42,16 +40,17 @@ initRemoteTable :: RemoteTable
4240initRemoteTable = BuiltIn.remoteTable (RemoteTable Map.empty Map.empty)
4341
4442resolveClosure :: RemoteTable -> StaticLabel -> ByteString -> Maybe Dynamic
45−-- Special support for call
46−resolveClosure rtable Call env = do
47− proc <- resolveClosure rtable label env'
48− sender <- rtable ^. remoteTableSender (dynTypeRep proc)
49− proc `bind` (sender `dynApp` toDyn (pid :: ProcessId))
43+-- Built-in closures
44+resolveClosure rtable ClosureSend env = do
45+ rss <- rtable ^. remoteTableDict label
46+ rssSend rss `dynApply` toDyn pid
5047 where
51− (label, env', pid) = decode env
52− bind = dynBind tyConProcess bindProcess
53− bindProcess :: Process a -> (a -> Process b) -> Process b
54− bindProcess = (>>=)
48+ (label, pid) = decode env :: (String, ProcessId)
49+resolveClosure rtable ClosureReturn env = do
50+ rss <- rtable ^. remoteTableDict label
51+ rssReturn rss `dynApply` toDyn arg
52+ where
53+ (label, arg) = decode env :: (String, ByteString)
5554-- Generic closure combinators
5655resolveClosure rtable ClosureApply env = do
5756 f <- resolveClosure rtable labelf envf
@@ -126,7 +125,3 @@ resolveClosure rtable CpApply env =
126125resolveClosure rtable (UserStatic label) env = do
127126 val <- rtable ^. remoteTableLabel label
128127 dynApply val (toDyn env)
129−
130−tyConProcess :: TyCon
131−tyConProcess = typeRepTyCon (typeOf (undefined :: Process ()))
132−
distributed-process/src/Control/Distributed/Process/Internal/Closure/BuiltIn.hs+17
@@ -2,14 +2,21 @@
22module Control.Distributed.Process.Internal.Closure.BuiltIn
33 ( remoteTable
44 , linkClosure
5+ , sendClosure
6+ , returnClosure
57 ) where
68
9+import Data.Binary (encode)
710import Control.Distributed.Process (link)
811import Control.Distributed.Process.Internal.Types
912 ( ProcessId
1013 , Closure
1114 , Process
1215 , RemoteTable
16+ , SerializableDict(..)
17+ , Closure(..)
18+ , Static(..)
19+ , StaticLabel(..)
1320 )
1421import Control.Distributed.Process.Internal.Closure.TH (remotable, mkClosure)
1522
@@ -21,3 +28,13 @@ remoteTable = __remoteTable
2128-- | Closure version of 'link'
2229linkClosure :: ProcessId -> Closure (Process ())
2330linkClosure = $(mkClosure 'link)
31+
32+-- | Closure version of 'send'
33+sendClosure :: SerializableDict a -> ProcessId -> Closure (a -> Process ())
34+sendClosure (SerializableDict label) pid =
35+ Closure (Static ClosureSend) (encode (label, pid))
36+
37+-- | Return any value
38+returnClosure :: SerializableDict a -> a -> Closure (Process a)
39+returnClosure (SerializableDict label) val =
40+ Closure (Static ClosureReturn) (encode (label, encode val))
distributed-process/src/Control/Distributed/Process/Internal/Closure/BuiltIn.hs-boot+4−1
@@ -5,8 +5,11 @@ import Control.Distributed.Process.Internal.Types
55 , Closure
66 , Process
77 , RemoteTable
8+ , SerializableDict
89 )
910
1011remoteTable :: RemoteTable -> RemoteTable
1112
12−linkClosure :: ProcessId -> Closure (Process ())
13+linkClosure :: ProcessId -> Closure (Process ())
14+sendClosure :: SerializableDict a -> ProcessId -> Closure (a -> Process ())
15+returnClosure :: SerializableDict a -> a -> Closure (Process a)
distributed-process/src/Control/Distributed/Process/Internal/Closure/TH.hs+26−37
@@ -10,7 +10,6 @@ module Control.Distributed.Process.Internal.Closure.TH
1010import Prelude hiding (lookup)
1111import Data.ByteString.Lazy (ByteString)
1212import Data.Binary (encode, decode)
13−import Data.Typeable (typeOf, Typeable, TypeRep)
1413import Data.Accessor ((^=))
1514import Control.Applicative ((<$>))
1615import Language.Haskell.TH
@@ -46,11 +45,12 @@ import Control.Distributed.Process.Internal.Types
4645 , StaticLabel(..)
4746 , Process
4847 , ProcessId
49− , CallReply(..)
5048 , procMsg
5149 , Identifier(ProcessIdentifier)
5250 , remoteTableLabel
53− , remoteTableSender
51+ , remoteTableDict
52+ , SerializableDict(..)
53+ , RuntimeSerializableSupport(..)
5454 )
5555import Control.Distributed.Process.Internal.Dynamic (Dynamic, toDyn)
5656import Control.Distributed.Process.Internal.MessageT (sendMessage)
@@ -64,10 +64,13 @@ import Control.Distributed.Process.Internal.MessageT (sendMessage)
6464remotable :: [Name] -> Q [Dec]
6565remotable ns = do
6666 (closures, inserts) <- unzip <$> mapM generateDefs ns
67− rtable <- createMetaData (concat inserts)
67+ rtable <- createMetaData inserts
6868 return $ concat closures ++ rtable
6969
7070-- | Create a closure
71+--
72+-- If @f :: a -> b@ then @mkClosure :: a -> Closure b@. Make sure to pass 'f'
73+-- as an argument to 'remotable' too.
7174mkClosure :: Name -> Q Exp
7275mkClosure = varE . closureName
7376
@@ -90,26 +93,18 @@ createMetaData is =
9093--
9194-- Moreover, if b is of the form Process c, then additionally create
9295-- 3. registerSender (Process c) (send :: ProcessId -> c -> Process ())
93−generateDefs :: Name -> Q ([Dec], [Q Exp])
96+generateDefs :: Name -> Q ([Dec], Q Exp)
9497generateDefs n = do
98+ serializableDict <- [t| SerializableDict |]
9599 mType <- getType n
96100 case mType of
97101 Just (origName, ArrowT `AppT` arg `AppT` res) -> do
98102 (closure, label) <- generateClosure origName (return arg) (return res)
99103 let decoder = generateDecoder origName (return res)
100104 insert = [| registerLabel $(stringE label) (toDyn $decoder) |]
101−
102− -- Generate special closure to support 'call'
103− mResult <- processResult res
104− insert' <- case mResult of
105− Nothing ->
106− return []
107− Just result -> do
108− let sender = generateSender result
109− return . return $
110− [| registerSender $(typeToTypeRep res) (toDyn $sender) |]
111−
112− return (closure, insert : insert')
105+ return (closure, insert)
106+ Just (origName, sdict `AppT` a) | sdict == serializableDict ->
107+ return ([], [| registerSerializableDict $(varE n) |])
113108 _ ->
114109 fail $ "remotable: " ++ show n ++ " is not a function"
115110
@@ -125,25 +120,10 @@ generateClosure n arg res = do
125120 label :: String
126121 label = show $ n
127122
128−-- | If 't' is of the form 'Process b', return 'Just b'
129−processResult :: Type -> Q (Maybe (Q Type))
130−processResult t = do
131− process <- [t| Process |]
132− case t of
133− p `AppT` a | p == process -> return . Just . return $ a
134− _ -> return Nothing
135−
136123-- | Generate the decoder (see 'generateDefs')
137124generateDecoder :: Name -> Q Type -> Q Exp
138125generateDecoder n res = [| $(varE n) . decode :: ByteString -> $res |]
139126
140−-- | Generate the sender. This is necessary to support 'call'
141−generateSender :: Q Type -> Q Exp
142−generateSender tp =
143− -- This duplicates the functionality of 'Process.send', but gets the TH out
144− -- of the mutually recursive module cycle
145− [| (\pid msg -> procMsg $ sendMessage (ProcessIdentifier pid) (CallReply msg)) :: ProcessId -> $tp -> Process () |]
146−
147127-- | The name for the function that generates the closure
148128closureName :: Name -> Name
149129closureName n = mkName $ nameBase n ++ "__closure"
@@ -151,16 +131,25 @@ closureName n = mkName $ nameBase n ++ "__closure"
151131registerLabel :: String -> Dynamic -> RemoteTable -> RemoteTable
152132registerLabel label dyn = remoteTableLabel label ^= Just dyn
153133
154−registerSender :: TypeRep -> Dynamic -> RemoteTable -> RemoteTable
155−registerSender typ dyn = remoteTableSender typ ^= Just dyn
134+registerSerializableDict :: forall a. SerializableDict a -> RemoteTable -> RemoteTable
135+registerSerializableDict (SerializableDict label) =
136+ -- TODO: Code duplication with Process
137+ let send :: ProcessId -> a -> Process ()
138+ send pid a = procMsg $ sendMessage (ProcessIdentifier pid) a
139+
140+ ret :: ByteString -> Process a
141+ ret = return . decode
142+
143+ rss = RuntimeSerializableSupport {
144+ rssSend = toDyn send
145+ , rssReturn = toDyn ret
146+ }
147+ in remoteTableDict label ^= Just rss
156148
157149--------------------------------------------------------------------------------
158150-- Generic Template Haskell auxiliary functions --
159151--------------------------------------------------------------------------------
160152
161−typeToTypeRep :: Type -> Q Exp
162−typeToTypeRep tp = [| typeOf (undefined :: $(return tp)) |]
163−
164153-- | Compose a set of expressions
165154compose :: [Q Exp] -> Q Exp
166155compose [] = [| id |]
distributed-process/src/Control/Distributed/Process/Internal/Types.hs+57−41
@@ -27,8 +27,9 @@ module Control.Distributed.Process.Internal.Types
2727 , StaticLabel(..)
2828 , Static(..)
2929 , Closure(..)
30− , CallReply(..)
3130 , RemoteTable(..)
31+ , SerializableDict(..)
32+ , RuntimeSerializableSupport(..)
3233 -- * Messages
3334 , Message(..)
3435 -- * Node controller user-visible data types
@@ -57,14 +58,14 @@ module Control.Distributed.Process.Internal.Types
5758 , typedChannels
5859 , typedChannelWithId
5960 , remoteTableLabels
60− , remoteTableSenders
61+ , remoteTableDicts
6162 , remoteTableLabel
62− , remoteTableSender
63+ , remoteTableDict
6364 ) where
6465
6566import Data.Map (Map)
6667import Data.Int (Int32)
67−import Data.Typeable (Typeable, TypeRep)
68+import Data.Typeable (Typeable)
6869import Data.Binary (Binary(put, get), putWord8, getWord8)
6970import Data.ByteString.Lazy (ByteString)
7071import Data.Accessor (Accessor, accessor)
@@ -208,8 +209,9 @@ data ReceivePort a =
208209
209210data StaticLabel =
210211 UserStatic String
211− -- Special support for 'call'
212− | Call
212+ -- Built-in closures
213+ | ClosureReturn
214+ | ClosureSend
213215 -- Generic closure combinators
214216 | ClosureApply
215217 | ClosureConst
@@ -234,16 +236,28 @@ newtype Static a = Static StaticLabel
234236data Closure a = Closure (Static (ByteString -> a)) ByteString
235237 deriving (Typeable, Show)
236238
237−-- | Used for the implementation of 'call'
238−newtype CallReply a = CallReply a
239− deriving (Typeable, Binary)
240−
241239-- | Used to fake 'static' (see paper)
242240data RemoteTable = RemoteTable {
241+ -- | If the user creates a closure of type @a -> Closure b@ from a function
242+ -- @f : a -> b@, then '_remoteTableLabels' should have an entry for "f"
243+ -- of type @ByteString -> b@ (basically, @f . encode@)
243244 _remoteTableLabels :: Map String Dynamic
244− , _remoteTableSenders :: Map TypeRep Dynamic
245+ -- | Runtime counterpart to SerializableDict
246+ , _remoteTableDicts :: Map String RuntimeSerializableSupport
245247 }
246248
249+-- | Reification of 'Serializable' (see "Control.Distributed.Process.Closure")
250+data SerializableDict a where
251+ SerializableDict :: Serializable a => String -> SerializableDict a
252+ deriving (Typeable)
253+
254+-- | Runtime support for implementing "polymorphic" functions with a
255+-- Serializable qualifier (sendClosure, returnClosure, ..).
256+data RuntimeSerializableSupport = RuntimeSerializableSupport {
257+ rssSend :: Dynamic
258+ , rssReturn :: Dynamic
259+ }
260+
247261--------------------------------------------------------------------------------
248262-- Messages --
249263--------------------------------------------------------------------------------
@@ -413,36 +427,38 @@ instance Binary Identifier where
413427
414428instance Binary StaticLabel where
415429 put (UserStatic string) = putWord8 0 >> put string
416− put Call = putWord8 1
417− put ClosureApply = putWord8 2
418− put ClosureConst = putWord8 3
419− put ClosureUnit = putWord8 4
420− put CpId = putWord8 5
421− put CpComp = putWord8 6
422− put CpFirst = putWord8 7
423− put CpSwap = putWord8 8
424− put CpCopy = putWord8 9
425− put CpLeft = putWord8 10
426− put CpMirror = putWord8 11
427− put CpUntag = putWord8 12
428− put CpApply = putWord8 13
430+ put ClosureReturn = putWord8 1
431+ put ClosureSend = putWord8 2
432+ put ClosureApply = putWord8 3
433+ put ClosureConst = putWord8 4
434+ put ClosureUnit = putWord8 5
435+ put CpId = putWord8 6
436+ put CpComp = putWord8 7
437+ put CpFirst = putWord8 8
438+ put CpSwap = putWord8 9
439+ put CpCopy = putWord8 10
440+ put CpLeft = putWord8 11
441+ put CpMirror = putWord8 12
442+ put CpUntag = putWord8 13
443+ put CpApply = putWord8 14
429444 get = do
430445 header <- getWord8
431446 case header of
432447 0 -> UserStatic <$> get
433− 1 -> return Call
434− 2 -> return ClosureApply
435− 3 -> return ClosureConst
436− 4 -> return ClosureUnit
437− 5 -> return CpId
438− 6 -> return CpComp
439− 7 -> return CpFirst
440− 8 -> return CpSwap
441− 9 -> return CpCopy
442− 10 -> return CpLeft
443− 11 -> return CpMirror
444− 12 -> return CpUntag
445− 13 -> return CpApply
448+ 1 -> return ClosureReturn
449+ 2 -> return ClosureSend
450+ 3 -> return ClosureApply
451+ 4 -> return ClosureConst
452+ 5 -> return ClosureUnit
453+ 6 -> return CpId
454+ 7 -> return CpComp
455+ 8 -> return CpFirst
456+ 9 -> return CpSwap
457+ 10 -> return CpCopy
458+ 11 -> return CpLeft
459+ 12 -> return CpMirror
460+ 13 -> return CpUntag
461+ 14 -> return CpApply
446462 _ -> fail "StaticLabel.get: invalid"
447463
448464
@@ -481,14 +497,14 @@ typedChannelWithId cid = typedChannels >>> DAC.mapMaybe cid
481497remoteTableLabels :: Accessor RemoteTable (Map String Dynamic)
482498remoteTableLabels = accessor _remoteTableLabels (\ls tbl -> tbl { _remoteTableLabels = ls })
483499
484−remoteTableSenders :: Accessor RemoteTable (Map TypeRep Dynamic)
485−remoteTableSenders = accessor _remoteTableSenders (\es tbl -> tbl { _remoteTableSenders = es })
500+remoteTableDicts :: Accessor RemoteTable (Map String RuntimeSerializableSupport)
501+remoteTableDicts = accessor _remoteTableDicts (\ds tbl -> tbl { _remoteTableDicts = ds })
486502
487503remoteTableLabel :: String -> Accessor RemoteTable (Maybe Dynamic)
488504remoteTableLabel label = remoteTableLabels >>> DAC.mapMaybe label
489505
490−remoteTableSender :: TypeRep -> Accessor RemoteTable (Maybe Dynamic)
491−remoteTableSender typ = remoteTableSenders >>> DAC.mapMaybe typ
506+remoteTableDict :: String -> Accessor RemoteTable (Maybe RuntimeSerializableSupport)
507+remoteTableDict label = remoteTableDicts >>> DAC.mapMaybe label
492508
493509--------------------------------------------------------------------------------
494510-- MessageT monad --
distributed-process/tests/TestClosure.hs+7−7
@@ -13,6 +13,9 @@ import Control.Distributed.Process.Closure
1313import Control.Distributed.Process.Node
1414import TestAuxiliary
1515
16+serializableDictInt :: SerializableDict Int
17+serializableDictInt = SerializableDict "serializableDictInt"
18+
1619addInt :: Int -> Int -> Int
1720addInt x y = x + y
1821
@@ -34,16 +37,13 @@ factorial n = (n *) <$> factorial (n - 1)
3437factorialOf :: () -> Int -> Process Int
3538factorialOf () = factorial
3639
37−returnInt :: Int -> Process Int
38−returnInt = return
39−
4040returnForTestApply :: (Closure (Int -> Process Int), Int) -> (Closure (Int -> Process Int), Int)
4141returnForTestApply = id
4242
4343wait :: Int -> Process ()
4444wait = liftIO . threadDelay
4545
46−$(remotable ['addInt, 'putInt, 'sendInt, 'sendPid, 'factorial, 'factorialOf, 'returnInt, 'returnForTestApply, 'wait])
46+$(remotable ['addInt, 'putInt, 'sendInt, 'sendPid, 'factorial, 'factorialOf, 'returnForTestApply, 'wait, 'serializableDictInt])
4747
4848testSendPureClosure :: Transport -> RemoteTable -> IO ()
4949testSendPureClosure transport rtable = do
@@ -148,7 +148,7 @@ testCall transport rtable = do
148148 node <- newLocalNode transport rtable
149149 nid <- readMVar serverNodeAddr
150150 runProcess node $ do
151− (120 :: Int) <- call nid ($(mkClosure 'factorial) 5)
151+ (120 :: Int) <- call serializableDictInt nid ($(mkClosure 'factorial) 5)
152152 liftIO $ putMVar clientDone ()
153153
154154 takeMVar clientDone
@@ -157,7 +157,7 @@ sendFac :: Int -> ProcessId -> Closure (Process ())
157157sendFac n pid = $(mkClosure 'factorial) n `cpBind` $(mkClosure 'sendInt) pid
158158
159159factorial' :: Int -> Closure (Process Int)
160−factorial' n = $(mkClosure 'returnInt) n `cpBind` $(mkClosure 'factorialOf) ()
160+factorial' n = returnClosure serializableDictInt n `cpBind` $(mkClosure 'factorialOf) ()
161161
162162testBind :: Transport -> RemoteTable -> IO ()
163163testBind transport rtable = do
@@ -181,7 +181,7 @@ testCallBind transport rtable = do
181181 node <- newLocalNode transport rtable
182182 nid <- readMVar serverNodeAddr
183183 runProcess node $ do
184− (120 :: Int) <- call nid (factorial' 5)
184+ (120 :: Int) <- call serializableDictInt nid (factorial' 5)
185185 liftIO $ putMVar clientDone ()
186186
187187 takeMVar clientDone