git.iko.soy/distributed-process
on master help sign in
Fix master/slave example.
commit0aecd1ae58baf2568052e23ba942b73774181011 authorNicolas Wu <nick@well-typed.com> dateTue 10 Jan 2012, 17:36 (15 years ago) parente2133b2
1 file changed+56−29
examples/DemoTCP.hs+56−29
examples/DemoTCP.hs+56−29
@@ -3,62 +3,89 @@ module Main where
33import Network.Transport
44import Network.Transport.TCP
55
6−import System.Environment
76import Control.Monad
7+import Network.Socket (HostName, ServiceName)
8+import System.Environment
9+
810import qualified Data.ByteString.Char8 as BS
911
12+import Debug.Trace
13+
1014type ChanId = Int
1115
1216-- | This example demonstrates how a master can be connected to slaves using
1317-- the transport layer.
1418main :: IO ()
1519main = do
16− [mode, numberStr, host, service, chanId] <- getArgs
17− case mode of
18− "master" -> do
19− let number = read numberStr
20+ args <- getArgs
21+ case args of
22+ -- Master:
23+ -- The master only provides the host, service, and slaves to expect.
24+ [host, service, sendAddrFilePath, number] -> do
25+ let numSlaves = read number
2026 transport <- mkTransport $ TCPConfig defaultHints host service
21−
22− (clients, masterReceiveEnd) <- demoMaster number transport host service
27+ (clientSendEnds, masterReceiveEnd) <- demoMaster transport sendAddrFilePath numSlaves
2328 zipWithM_
2429 (\clientSendEnd clientId -> send clientSendEnd [BS.pack . show $ clientId])
25− clients [0 .. number-1]
26− replicateM_ number $ do
30+ clientSendEnds [0 .. numSlaves-1]
31+ replicateM_ numSlaves $ do
2732 [clientMessage] <- receive masterReceiveEnd
2833 print clientMessage
2934
30− "slave" -> do
31− (masterSendEnd, slaveReceiveEnd) <- demoSlave transport host service
35+ -- Slave:
36+ -- Each slave provides its own host and service, as well as details of
37+ -- the master it wishes to connect to.
38+ [host, service, sendAddrFilePath] -> do
39+ transport <- mkTransport $ TCPConfig defaultHints host service
40+ (masterSendEnd, slaveReceiveEnd) <- demoSlave transport sendAddrFilePath
3241 [clientId] <- receive slaveReceiveEnd
42+ putStrLn $ "slave: received clientId: " ++ show clientId
3343 let message = "Connected to slave: " ++ BS.unpack clientId
44+
3445 send masterSendEnd [BS.pack message]
46+ putStrLn "slave: sent message to master"
47+
48+ _ -> error "Unexpected arguments"
3549
36−demoMaster :: Int -- ^ Number of slaves
37− -> Transport -- ^ Transport
38− -> HostName -- ^ HostName of the master node
39− -> ServiceName -- ^ ServiceName of the master node
50+demoMaster :: Transport -- ^ Transport
51+ -> FilePath -- ^ File to write SendAddr
52+ -> Int -- ^ Number of slaves to expect
4053 -> IO ([SendEnd], ReceiveEnd)
41−demoMaster numSlaves transport host service = do
42− trans <- mkTransport defaultHints host service
43− (sendAddr, receiveEnd) <- connect trans
44− putStrLn $ "Master sendAddr:" ++ show . serialize $ sendAddr
54+demoMaster transport sendAddrFilePath numSlaves = do
55+ -- Establish an initial transport
56+ (sendAddr, receiveEnd) <- newConnection transport
57+
58+ -- Write a file containing the sendAddr
59+ putStrLn $ "master: writing sendAddr file:" ++ (show . serialize $ sendAddr)
60+ BS.writeFile sendAddrFilePath $ serialize sendAddr
4561
62+ -- Deserialize each of the sendEnds received by the slaves
4663 sendEnds <- replicateM numSlaves $ do
4764 [bytes] <- receive receiveEnd
65+ putStrLn "master: received connection."
4866 case deserialize transport bytes of
49− Nothing -> fail "Garbage message from slave"
67+ Nothing -> fail "Garbage message from slave!"
5068 Just sendAddr -> connect sendAddr
5169 return (sendEnds, receiveEnd)
5270
5371demoSlave :: Transport -- ^ Transport
54− -> HostName -- ^ The master HostName
55− -> ServiceName -- ^ The master ServiceName
56− -> ChanId -- ^ The master ChanId
72+ -> FilePath -- ^ File to read SendAddr
5773 -> IO (SendEnd, ReceiveEnd)
58−demoSlave transport host service chanId = do
59− sendAddr <- mkSendAddr host service chanId
60− (selfSendAddr, selfReceiveEnd) <- newConnection transport
61− sendEnd <- connect (newSendAddr host service)
62− send sendEnd [serialize selfSendAddr]
63− return (sendEnd, selfReceiveEnd)
74+demoSlave transport masterSendAddrFilePath = do
75+ -- Create a new connection on the transport
76+ (sendAddr, receiveEnd) <- newConnection transport
77+
78+ -- Establish connection with the master
79+ bytes <- BS.readFile masterSendAddrFilePath
80+ case deserialize transport bytes of
81+ Just masterSendAddr -> do
82+ putStrLn $ "slave: connecting to sendAddr: " ++ (show . serialize $ masterSendAddr)
83+ masterSendEnd <- connect masterSendAddr
84+
85+ -- Send the serialized address of this slave
86+ send masterSendEnd [serialize sendAddr]
87+ putStrLn "slave: sent sendAddr"
88+ return (masterSendEnd, receiveEnd)
89+
90+ Nothing -> error "slave: Unable to deserialize master SendAddr!"
6491