1{-# LANGUAGE CPP, BangPatterns #-}
5import Network.Transport (newConnection, receive, connect, send, defaultHints,
6 serialize, deserialize, SourceEnd, TargetEnd)
7import Network.Transport.TCP (mkTransport, TCPConfig (..))
9import Control.Monad (forever, replicateM_, forM_)
11import qualified Data.Serialize as Ser
12import Data.Maybe (fromJust)
14import System.Environment (getArgs, withArgs)
15import Data.Time (getCurrentTime, diffUTCTime)
16import System.IO (withFile, IOMode(..), hPutStrLn)
17import Control.Concurrent (forkIO)
18import Control.Concurrent.MVar (newEmptyMVar, takeMVar, putMVar)
21import qualified Data.ByteString.Char8 as BS
22import qualified Network.Socket.ByteString as NBS
26import qualified Data.ByteString.Lazy.Char8 as BS
27import qualified Network.Socket.ByteString.Lazy as NBS
28encode = Ser.encodeLazy
29decode = Ser.decodeLazy
33encode :: Ser.Serialize a => a -> BS.ByteString
34decode :: Ser.Serialize a => BS.ByteString -> Either String a
38-- | This performs a ping benchmark on the TCP transport. This can be
41-- ghc --make -idistributed-process/src -inetwork-transport/src -O2 benchmarks/PingTransport.hs
43-- To use the compiled binary, first set up a server:
45-- ./benchmarks/PingTransport server 0.0.0.0 8080 sourceAddr
47-- Once this is established, launch a client to perform the benchmark. The
48-- following command sends 1000 pings per mark.
50-- ./benchmarks/PingTransport client 0.0.0.0 8081 sourceAddr 1000
52-- The server must be restarted between benchmarks.
56 serverAddr <- newEmptyMVar
57 clientAddr <- newEmptyMVar
61 -- establish transport
62 transport <- mkTransport $ TCPConfig defaultHints "127.0.0.1" "8080"
65 putStrLn "server: creating ping end"
66 (sourceAddrPing, targetEndPing) <- newConnection transport
67 putMVar serverAddr sourceAddrPing
70 putStrLn "server: creating pong end"
71 sourceAddrPong <- takeMVar clientAddr
72 sourceEndPong <- connect sourceAddrPong
74 -- always respond to a ping with a pong
75 putStrLn "server: awaiting pings"
76 pong targetEndPing sourceEndPong
79 sourceAddr <- takeMVar serverAddr
80 let pings = read pingsStr
81 -- establish transport
82 transport <- mkTransport $ TCPConfig defaultHints "127.0.0.1" "8081"
85 sourceEndPing <- connect sourceAddr
88 (sourceAddrPong, targetEndPong) <- newConnection transport
89 putMVar clientAddr sourceAddrPong
91 ping sourceEndPing targetEndPong pings
92 putStrLn "Done with all ping/pongs."
94-- | The message we use to ping (CAF so that we don't keep encoding it)
95pingMessage :: BS.ByteString
96pingMessage = BS.pack "ping123"
98-- | Keep replying to pings (send pongs)
99pong :: TargetEnd -> SourceEnd -> IO ()
100pong targetEndPing sourceEndPong = do
101 [bs] <- receive targetEndPing
102 -- putStrLn $ "server got " ++ BS.unpack bs
103 send sourceEndPong [bs]
104 pong targetEndPing sourceEndPong
106-- | Send a number of pings
107ping :: SourceEnd -> TargetEnd -> Int -> IO ()
108ping sourceEndPing targetEndPong pings = go [] pings
110 go :: [Double] -> Int -> IO ()
113 putStrLn $ "client did " ++ show pings ++ " pings"
115 before <- getCurrentTime
116 send sourceEndPing [pingMessage]
117 [bs] <- receive targetEndPong
118 -- putStrLn $ "client got " ++ BS.unpack bs
119 after <- getCurrentTime
120 let latency = (1e6 :: Double) * realToFrac (diffUTCTime after before)
121 latency `seq` go (latency : rtl) (i - 1)
123-- | Output latencies to a file to be plotted
124outputData :: [Double] -> IO ()
126 withFile "round-trip-latency-tcp-transport.data" WriteMode $ \h ->
127 forM_ (zip [0..] rtl) $ \(i, latency) ->
128 hPutStrLn h $ (show i) ++ " " ++ (show latency)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list