@@ -1,16 +1,22 @@
1module Main where
1module Main where
3+-- TODO: Merge with PingTCPTransport and factor differences.
3−import Network.Transport
5+import Network.Transport (newConnection, receive, connect, send,
6+ serialize, deserialize, SourceEnd, TargetEnd)
4import Network.Transport.Pipes (mkTransport)
7import Network.Transport.Pipes (mkTransport)
6import Control.Monad (forever, replicateM_)
9import Control.Monad (forever, replicateM_)
7−import Criterion.Main (Benchmark, bench, defaultMain, nfIO)
10+import Criterion.Main (Benchmark, bench, defaultMainWith, nfIO)
11+import Criterion.Config (defaultConfig, ljust, Config(cfgSamples))
8−import Data.Binary
12+-- import Data.Binary (encode,decode)
13+import Data.Serialize (encode,decode)
9import Data.Maybe (fromJust)
14import Data.Maybe (fromJust)
10import Data.Int
15import Data.Int
11import System.Environment (getArgs, withArgs)
16import System.Environment (getArgs, withArgs)
13−import qualified Data.ByteString.Lazy.Char8 as BS
18+-- import qualified Data.ByteString.Lazy.Char8 as LBS
19+import qualified Data.ByteString.Char8 as BS
15-- | This performs a ping benchmark on the TCP transport. This can be
21-- | This performs a ping benchmark on the TCP transport. This can be
16-- compiled using:
22-- compiled using:
@@ -50,7 +56,7 @@ main = do
50 forever $ pong targetEndPing sourceEndPong
56 forever $ pong targetEndPing sourceEndPong
53− "client" : sourceAddrFilePath : pingsStr : args' -> do
59+ "client" : sourceAddrFilePath : pingsStr : reps : args' -> do
54 let pings = read pingsStr
60 let pings = read pingsStr
55 -- establish transport
61 -- establish transport
56 transport <- mkTransport
62 transport <- mkTransport
@@ -64,10 +70,17 @@ main = do
64 send sourceEndPing [serialize sourceAddrPong]
70 send sourceEndPing [serialize sourceAddrPong]
66 -- benchmark the pings
72 -- benchmark the pings
73+ case (read reps) :: Int of
74+ 0 -> error "What would zero reps mean?"
75+ 1 -> do putStrLn "Because you're timing only one trial, skipping Criterion..."
76+ replicateM_ pings (ping sourceEndPing targetEndPong)
77+ n -> withArgs args' $ defaultMainWith
78+ (defaultConfig{ cfgSamples = ljust n })
79+ (return ()) -- Init action.
67−-- withArgs args' $ defaultMain [ benchPing sourceEndPing targetEndPong pings]
80+ [ benchPing sourceEndPing targetEndPong (fromIntegral pings) ]
68− replicateM_ pings (ping sourceEndPing targetEndPong)
69 putStrLn "Done with all ping/pongs."
81 putStrLn "Done with all ping/pongs."
71-- | This function takes a `TargetEnd` for the pings, and a `SourceEnd` for
84-- | This function takes a `TargetEnd` for the pings, and a `SourceEnd` for
72-- pongs. Whenever a ping is received from the `TargetEnd`, a pong is sent
85-- pongs. Whenever a ping is received from the `TargetEnd`, a pong is sent
73-- in reply down the `SourceEnd`, repeating whatever was sent.
86-- in reply down the `SourceEnd`, repeating whatever was sent.
@@ -81,9 +94,14 @@ pong targetEndPing sourceEndPong = do
81-- `targetEndPong`, which is then returned.
94-- `targetEndPong`, which is then returned.
82ping :: SourceEnd -> TargetEnd -> IO Int64
95ping :: SourceEnd -> TargetEnd -> IO Int64
83ping sourceEndPing targetEndPong = do
96ping sourceEndPing targetEndPong = do
84− send sourceEndPing [BS.empty]
97+ -- send sourceEndPing [BS.empty]
98+ send sourceEndPing [encode (42 :: Int64)]
85 [bs] <- receive targetEndPong
100 [bs] <- receive targetEndPong
86− return $ decode bs
101+-- return $ decode bs
103+ Left err -> error$ "decode failure: " ++ err
88-- | The effect of `benchPing sourceEndPing targetEndPong n` is to send
106-- | The effect of `benchPing sourceEndPing targetEndPong n` is to send
89-- `n` pings down `sourceEndPing` using the `ping` function. The time
107-- `n` pings down `sourceEndPing` using the `ping` function. The time