5import Network.Transport
6import Network.Transport.TCP (mkTransport, TCPConfig (..))
8import Control.Monad (forever, replicateM_)
9import Criterion.Main (Benchmark, bench, defaultMain, nfIO)
10import qualified Data.Serialize as Ser
11import Data.Maybe (fromJust)
13import System.Environment (getArgs, withArgs)
16import qualified Data.ByteString.Char8 as BS
17import qualified Network.Socket.ByteString as NBS
21import qualified Data.ByteString.Lazy.Char8 as BS
22import qualified Network.Socket.ByteString.Lazy as NBS
23encode = Ser.encodeLazy
24decode = Ser.decodeLazy
28encode :: Ser.Serialize a => a -> BS.ByteString
29decode :: Ser.Serialize a => BS.ByteString -> Either String a
33-- | This performs a ping benchmark on the TCP transport. This can be
36-- ghc --make -idistributed-process/src -inetwork-transport/src -O2 benchmarks/PingTransport.hs
38-- To use the compiled binary, first set up a server:
40-- ./benchmarks/PingTransport server 0.0.0.0 8080 sourceAddr
42-- Once this is established, launch a client to perform the benchmark. The
43-- following command sends 1000 pings per mark.
45-- ./benchmarks/PingTransport client 0.0.0.0 8081 sourceAddr 1000
47-- The server must be restarted between benchmarks.
52 "server" : host : service : sourceAddrFilePath : [] -> do
53 -- establish transport
54 transport <- mkTransport $ TCPConfig defaultHints host service
57 putStrLn "server: creating ping end"
58 (sourceAddrPing, targetEndPing) <- newConnection transport
59 BS.writeFile sourceAddrFilePath $ serialize sourceAddrPing
62 putStrLn "server: creating pong end"
63 [sourceAddrPongBS] <- receive targetEndPing
64 sourceEndPong <- connect . fromJust $ deserialize transport sourceAddrPongBS
66 -- always respond to a ping with a pong
67 putStrLn "server: awaiting pings"
68 forever $ pong targetEndPing sourceEndPong
71 "client" : host : service : sourceAddrFilePath : pingsStr : args' -> do
72 let pings = read pingsStr
73 -- establish transport
74 transport <- mkTransport $ TCPConfig defaultHints host service
77 sourceAddrPingBS <- BS.readFile sourceAddrFilePath
78 sourceEndPing <- connect . fromJust $ deserialize transport sourceAddrPingBS
81 (sourceAddrPong, targetEndPong) <- newConnection transport
82 send sourceEndPing [serialize sourceAddrPong]
84 -- benchmark the pings
85 withArgs args' $ defaultMain [ benchPing sourceEndPing targetEndPong pings]
86-- replicateM_ pings (ping sourceEndPing targetEndPong)
88-- | This function takes a `TargetEnd` for the pings, and a `SourceEnd` for
89-- pongs. Whenever a ping is received from the `TargetEnd`, a pong is sent
90-- in reply down the `SourceEnd`, repeating whatever was sent.
91pong :: TargetEnd -> SourceEnd -> IO ()
92pong targetEndPing sourceEndPong = do
93 bs <- receive targetEndPing
96-- | The effect of `ping sourceEndPing targetEndPong n` is to send the number
97-- `n` using `sourceEndPing`, and to then receive the a number from
98-- `targetEndPong`, which is then returned.
99ping :: SourceEnd -> TargetEnd -> Int64 -> IO Int64
100ping sourceEndPing targetEndPong n = do
101 send sourceEndPing [encode n]
102 [bs] <- receive targetEndPong
103 let (Right n) = decode bs
106-- | The effect of `benchPing sourceEndPing targetEndPong n` is to send
107-- `n` pings down `sourceEndPing` using the `ping` function. The time
108-- taken is benchmarked.
109benchPing :: SourceEnd -> TargetEnd -> Int64 -> Benchmark
110benchPing sourceEndPing targetEndPong n = bench "PingTransport" $
111 nfIO (replicateM_ (fromIntegral n) (ping sourceEndPing targetEndPong 42))
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