git.iko.soy/distributed-process
on master help sign in
Start the CH layer with the new transport
commitdc2e1d8111daaad11d8cc6a64d25f5229ba170fd authorEdsko de Vries <edsko@edsko.net> dateTue 5 Jun 2012, 17:41 (14 years ago) parent70cd9bb
4 files changed+108−33
distributed-process/distributed-process.cabal+5−4 distributed-process/src/Control/Distributed/Process.hs+35−29 distributed-process/src/Control/Distributed/Process/Internal/CQueue.hs+39 distributed-process/src/Control/Distributed/Process/Serializable.hs+29
distributed-process/distributed-process.cabal+5−4
@@ -1,9 +1,9 @@
11Name: distributed-process
2−Version: 0.0.1
2+Version: 0.1.0
33Description: Distributed processes for message based concurrency.
44License: BSD3
55License-file: LICENSE
6−Author: Duncan Coutts, Nicolas Wu
6+Author: Duncan Coutts, Nicolas Wu, Edsko de Vries
77Maintainer: duncan@well-typed.com
88Homepage: http://github.com/haskell-distributed/
99Build-Type: Simple
@@ -14,8 +14,9 @@ Library
1414 bytestring >= 0.9,
1515 containers >= 0.4,
1616 mtl >= 2.0,
17− network-transport >= 0.0
17+ binary,
18+ network-transport >= 0.1
1819 Exposed-modules: Control.Distributed.Process
19− Extensions: ExplicitForAll ScopedTypeVariables
20+ Extensions: ExplicitForAll, ScopedTypeVariables, GeneralizedNewtypeDeriving, FlexibleInstances, UndecidableInstances
2021 ghc-options: -Wall
2122 HS-Source-Dirs: src
distributed-process/src/Control/Distributed/Process.hs+35−29
@@ -1,3 +1,37 @@
1+module Control.Distributed.Process ( expect ) where
2+
3+import Data.ByteString.Lazy (ByteString)
4+import Data.Typeable (Typeable(typeOf))
5+import Data.Binary (decode)
6+import Control.Monad.Reader (MonadReader(..), ReaderT, liftIO)
7+import Control.Applicative ((<$>))
8+import Control.Distributed.Process.Internal.CQueue ( CQueue
9+ , dequeueMatching
10+ )
11+import Control.Distributed.Process.Serializable ( Serializable
12+ , Fingerprint
13+ , encodeFingerprint
14+ , fingerprint
15+ )
16+
17+data Message = Message { messageFingerprint :: Fingerprint
18+ , messageEncoding :: ByteString
19+ }
20+
21+data ProcessState = ProcessState { processQueue :: CQueue Message }
22+
23+newtype Process a = Process (ReaderT ProcessState IO a)
24+ deriving (Monad)
25+
26+expect :: forall a. Serializable a => Process a
27+expect = Process $ do
28+ queue <- processQueue <$> ask
29+ let fp = fingerprint (undefined :: a)
30+ msg <- liftIO $ dequeueMatching queue ((== fp) . messageFingerprint)
31+ return (decode . messageEncoding $ msg)
32+
33+
34+{-
135{-# LANGUAGE CPP, ExplicitForAll, ScopedTypeVariables #-}
236
337module Control.Distributed.Process (
@@ -198,33 +232,5 @@ monitorProcess :: ProcessId -> ProcessId -> MonitorAction -> Process ()
198232
199233-}
200234
201−-- Concurrent queue for single reader, single writer
202235--
203−data CQueue a = CQueue (MVar [a]) -- arrived
204− (Chan a) -- incomming
205−
206−newCQueue :: IO (CQueue a)
207−newCQueue = do
208− arrived <- newMVar []
209− incomming <- newChan
210− return (CQueue arrived incomming)
211−
212−enqueue :: CQueue a -> a -> IO ()
213−enqueue (CQueue _arrived incomming) a = writeChan incomming a
214−
215−dequeueMatching :: forall a. CQueue a -> (a -> Bool) -> IO a
216−dequeueMatching (CQueue arrived incomming) matches = do
217− modifyMVar arrived (checkArrived [])
218− where
219− checkArrived :: [a] -> [a] -> IO ([a], a)
220− checkArrived xs' [] = checkIncomming xs'
221− checkArrived xs' (x:xs)
222− | matches x = return (reverse xs' ++ xs, x)
223− | otherwise = checkArrived (x:xs') xs
224−
225− checkIncomming :: [a] -> IO ([a], a)
226− checkIncomming xs' = do
227− x <- readChan incomming
228− if matches x
229− then return (reverse xs', x)
230− else checkIncomming (x:xs')
236+-}
distributed-process/src/Control/Distributed/Process/Internal/CQueue.hsnew file+39
@@ -0,0 +1,39 @@
1+-- | Concurrent queue for single reader, single writer
2+module Control.Distributed.Process.Internal.CQueue
3+ ( CQueue
4+ , newCQueue
5+ , enqueue
6+ , dequeueMatching
7+ ) where
8+
9+import Control.Concurrent.MVar (MVar, newMVar, modifyMVar)
10+import Control.Concurrent.Chan (Chan, newChan, writeChan, readChan)
11+
12+data CQueue a = CQueue (MVar [a]) -- arrived
13+ (Chan a) -- incoming
14+
15+newCQueue :: IO (CQueue a)
16+newCQueue = do
17+ arrived <- newMVar []
18+ incoming <- newChan
19+ return (CQueue arrived incoming)
20+
21+enqueue :: CQueue a -> a -> IO ()
22+enqueue (CQueue _arrived incoming) = writeChan incoming
23+
24+dequeueMatching :: forall a. CQueue a -> (a -> Bool) -> IO a
25+dequeueMatching (CQueue arrived incoming) matches =
26+ modifyMVar arrived (checkArrived [])
27+ where
28+ checkArrived :: [a] -> [a] -> IO ([a], a)
29+ checkArrived xs' [] = checkIncomming xs'
30+ checkArrived xs' (x:xs)
31+ | matches x = return (reverse xs' ++ xs, x)
32+ | otherwise = checkArrived (x:xs') xs
33+
34+ checkIncomming :: [a] -> IO ([a], a)
35+ checkIncomming xs' = do
36+ x <- readChan incoming
37+ if matches x
38+ then return (reverse xs', x)
39+ else checkIncomming (x:xs')
distributed-process/src/Control/Distributed/Process/Serializable.hsnew file+29
@@ -0,0 +1,29 @@
1+module Control.Distributed.Process.Serializable
2+ ( Serializable
3+ , encodeFingerprint
4+ , fingerprint
5+ , Fingerprint
6+ ) where
7+
8+import Data.Binary (Binary)
9+import Data.Typeable (Typeable(..))
10+import Data.Typeable.Internal (TypeRep(TypeRep))
11+import GHC.Fingerprint.Type (Fingerprint(Fingerprint))
12+import Data.ByteString (ByteString)
13+import qualified Data.ByteString.Internal as BSI (unsafeCreate)
14+import Foreign.Storable (pokeByteOff)
15+
16+class (Binary a, Typeable a) => Serializable a
17+instance (Binary a, Typeable a) => Serializable a
18+
19+-- | Encode type representation as a bytestring
20+encodeFingerprint :: Fingerprint -> ByteString
21+encodeFingerprint (Fingerprint hi lo) =
22+ -- Since all CH nodes will run precisely the same binary, we don't have to
23+ -- worry about cross-arch issues here (like endianness)
24+ BSI.unsafeCreate 16 $ \p -> do
25+ pokeByteOff p 0 hi
26+ pokeByteOff p 8 lo
27+
28+fingerprint :: Typeable a => a -> Fingerprint
29+fingerprint a = let TypeRep fp _ _ = typeOf a in fp