Add createConnectedBufferedChannels with simple delay model
Crude approximation of GSV style.
-- | Create a pair of channels that are connected via buffers with delays.
--
-- This is a crude approximation of asynchronous network connections where
-- there is delay across the connection, and a limit on in-flight data.
--
-- The buffer size is bounded. It /blocks/ when 'send' would exceed the maximum
-- buffer size. The size per channel element is provided by a function, so this
-- can be size in bytes or a fixed size (e.g. 1 per element), so the max size
-- should be interpreted accordingly.
--
-- The delays are modeled in a simplistic "GSV" style:
--
-- * The G is the minimum latency for a 0 sized message.
-- * The S is the time per message size unit.
-- * The V is the variance in latency, which is assumed to be uniform in the
-- range @0..v@.
--
-- The sender is delayed by S. The receiver is delayed until the arrival time
-- which is G + S + V.
--
-- Note that this implementation does not handle the delays correctly if there
-- are multiple writers or multiple readers.
--
-- This is primarily useful for testing protocols.
--
createConnectedDelayChannels
:: forall m prng a.
(MonadSTM m, MonadTime m, MonadTimer m, RandomGen prng)
=> (a -> Int) -- ^ Data size measure
-> Int -- ^ Max size of data in-flight
-> (DiffTime, DiffTime, DiffTime) -- ^ GSV
-> prng -- ^ PRNG for sampling V
-> m (Channel m a, Channel m a)
Test included to check that the delays we get are what we expect.
-- Note that this implementation does not handle the delays correctly if there -- are multiple writers or multiple readers.
The consensus tests are using a single channel per mini-protocol, so it should work.
@nfrisby I presume we don't need this now right? Or would it still be useful to tidy this up?
tl; dr - I'm not currently planning on relying on this.
I used a different implementation for my PR that was doing similar things. But it's been so long that I can't really explain the difference -- I think we wrote them in parallel, if I recall correctly. They might have slightly different invariants too, with a particular focus on my intention to make sure the accumulated latencies didn't breach over into the next slot, since that is in some ways a "network partition" at that point. My test Propertys still aren't ready for those :(