33{-# LANGUAGE NamedFieldPuns #-}
44{-# LANGUAGE RankNTypes #-}
55{-# LANGUAGE ScopedTypeVariables #-}
6+ {-# LANGUAGE TypeApplications #-}
67
78module 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
2931import qualified Data.ByteString as BS
3032import qualified Data.ByteString.Lazy as LBS
3133import Data.ByteString.Lazy.Internal (smallChunkSize )
34+ import Data.Proxy
3235import 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 )
132135createConnectedChannels = 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.
0 commit comments