Skip to content

Commit 5ef5f2d

Browse files
committed
typed-protocols-examples: unbounded buffered channel
A channel based on `TQueue`. It is useful for testing pipelined protocols, where pipelining depth is not taken into account.
1 parent 74a64f2 commit 5ef5f2d

File tree

3 files changed

+37
-5
lines changed

3 files changed

+37
-5
lines changed

typed-protocols-examples/src/Network/TypedProtocol/Channel.hs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{-# LANGUAGE NamedFieldPuns #-}
44
{-# LANGUAGE RankNTypes #-}
55
{-# LANGUAGE ScopedTypeVariables #-}
6+
{-# LANGUAGE TypeApplications #-}
67

78
module Network.TypedProtocol.Channel
89
( Channel (..)
@@ -16,6 +17,7 @@ module Network.TypedProtocol.Channel
1617
#endif
1718
, createConnectedChannels
1819
, createConnectedBufferedChannels
20+
, createConnectedBufferedChannelsUnbounded
1921
, createPipelineTestChannels
2022
, channelEffect
2123
, delayChannel
@@ -29,6 +31,7 @@ import Control.Monad.Class.MonadTimer.SI
2931
import qualified Data.ByteString as BS
3032
import qualified Data.ByteString.Lazy as LBS
3133
import Data.ByteString.Lazy.Internal (smallChunkSize)
34+
import Data.Proxy
3235
import Numeric.Natural
3336

3437
#if !defined(mingw32_HOST_OS)
@@ -128,12 +131,20 @@ mvarsAsChannel bufferRead bufferWrite =
128131
--
129132
-- This is primarily useful for testing protocols.
130133
--
131-
createConnectedChannels :: MonadSTM m => m (Channel m a, Channel m a)
134+
createConnectedChannels :: forall m a. (MonadLabelledSTM m, MonadTraceSTM m, Show a) => m (Channel m a, Channel m a)
132135
createConnectedChannels = do
133136
-- Create two TMVars to act as the channel buffer (one for each direction)
134137
-- and use them to make both ends of a bidirectional channel
135-
bufferA <- atomically $ newEmptyTMVar
136-
bufferB <- atomically $ newEmptyTMVar
138+
bufferA <- atomically $ do
139+
v <- newEmptyTMVar
140+
labelTMVar v "buffer-a"
141+
traceTMVar (Proxy @m) v $ \_ a -> pure $ TraceString ("buffer-a: " ++ show a)
142+
return v
143+
bufferB <- atomically $ do
144+
v <- newEmptyTMVar
145+
traceTMVar (Proxy @m) v $ \_ a -> pure $ TraceString ("buffer-b: " ++ show a)
146+
labelTMVar v "buffer-b"
147+
return v
137148

138149
return (mvarsAsChannel bufferB bufferA,
139150
mvarsAsChannel bufferA bufferB)
@@ -165,6 +176,27 @@ createConnectedBufferedChannels sz = do
165176
recv = atomically (Just <$> readTBQueue bufferRead)
166177

167178

179+
-- | Create a pair of channels that are connected via two unbounded buffers.
180+
--
181+
-- This is primarily useful for testing protocols.
182+
--
183+
createConnectedBufferedChannelsUnbounded :: forall m a. MonadSTM m
184+
=> m (Channel m a, Channel m a)
185+
createConnectedBufferedChannelsUnbounded = do
186+
-- Create two TQueues to act as the channel buffers (one for each
187+
-- direction) and use them to make both ends of a bidirectional channel
188+
bufferA <- newTQueueIO
189+
bufferB <- newTQueueIO
190+
191+
return (queuesAsChannel bufferB bufferA,
192+
queuesAsChannel bufferA bufferB)
193+
where
194+
queuesAsChannel bufferRead bufferWrite =
195+
Channel{send, recv}
196+
where
197+
send x = atomically (writeTQueue bufferWrite x)
198+
recv = atomically ( Just <$> readTQueue bufferRead)
199+
168200
-- | Create a pair of channels that are connected via N-place buffers.
169201
--
170202
-- This variant /fails/ when 'send' would exceed the maximum buffer size.

typed-protocols-examples/test/Network/TypedProtocol/PingPong/Tests.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ prop_connect_pipelined5 choices (Positive omax) (NonNegative n) =
303303

304304
-- | Run a non-pipelined client and server over a channel using a codec.
305305
--
306-
prop_channel :: (MonadSTM m, MonadAsync m, MonadCatch m)
306+
prop_channel :: (MonadLabelledSTM m, MonadTraceSTM m, MonadAsync m, MonadCatch m)
307307
=> NonNegative Int
308308
-> m Bool
309309
prop_channel (NonNegative n) = do

typed-protocols-examples/test/Network/TypedProtocol/ReqResp/Tests.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ prop_connectPipelined cs f xs =
189189
-- Properties using channels, codecs and drivers.
190190
--
191191

192-
prop_channel :: (MonadSTM m, MonadAsync m, MonadCatch m)
192+
prop_channel :: (MonadLabelledSTM m, MonadTraceSTM m, MonadAsync m, MonadCatch m)
193193
=> (Int -> Int -> (Int, Int)) -> [Int]
194194
-> m Bool
195195
prop_channel f xs = do

0 commit comments

Comments
 (0)