remote-0.1: examples/tests/Test-Message.hs
{-# LANGUAGE DeriveDataTypeable,TemplateHaskell #-}
module Main where
-- A convoluted example showing some different ways
-- messages can be passed between processes.
import Remote
import Data.Typeable (Typeable)
import Data.Data (Data)
import Data.Binary (Binary,get,put)
import System.Random (randomR,getStdRandom)
import Control.Concurrent (threadDelay)
import Control.Monad (when)
import Control.Monad.Trans (liftIO)
data Chunk = Chunk Int deriving (Typeable,Data)
instance Binary Chunk where
get = genericGet
put = genericPut
slaveWorker :: ProcessM ()
slaveWorker =
receiveWait [match(\sndport -> mapM (sendrand sndport) [0..50] >> sendChannel sndport (Chunk 0))]
where sendrand sndport _ =
do newval <- liftIO $ getStdRandom (randomR (1,100))
sendChannel sndport (Chunk newval)
$( remotable ['slaveWorker] )
testNode :: ProcessId -> ProcessM ()
testNode pid =
let getvals mainpid rcv =
do (Chunk val) <- receiveChannel rcv
send mainpid val
when (val /= 0)
(getvals mainpid rcv)
in
do (sendport, receiveport) <- newChannel
self <- getSelfPid
send pid sendport
spawnLocal $ getvals self receiveport
return ()
initialProcess "MASTER" =
do peers <- getPeers
let slaves = findPeerByRole peers "SLAVE"
slavepids <- mapM (\slave -> spawn slave slaveWorker__closure) slaves
mapM_ testNode slavepids
let getsome =
do res <- receiveWait [match(\i -> say ("Got " ++ show (i::Int)) >> return (i/=0))]
when res getsome
mapM_ (const getsome) slaves
initialProcess "SLAVE" = receiveWait []
main = remoteInit (Just "config") [Main.__remoteCallMetaData] initialProcess