-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Multiplexing library
--   
--   Multiplexing library
@package network-mux
@version 0.1.0.0

module Control.Concurrent.JobPool
data JobPool m a
data Job m a
Job :: m a -> (SomeException -> a) -> String -> Job m a
withJobPool :: forall m a b. (MonadAsync m, MonadThrow m) => (JobPool m a -> m b) -> m b
forkJob :: forall m a. (MonadAsync m, MonadMask m) => JobPool m a -> Job m a -> m ()
readSize :: MonadSTM m => JobPool m a -> STM m Int
collect :: MonadSTM m => JobPool m a -> STM m a


-- | An extension of <a>Channel</a>, with additional <a>Channel</a>
--   implementations.
module Network.Mux.Channel
data Channel m
Channel :: (ByteString -> m ()) -> m (Maybe ByteString) -> Channel m

-- | Write bytes to the channel.
--   
--   It maybe raise exceptions.
[send] :: Channel m -> ByteString -> m ()

-- | Read some input from the channel, or <tt>Nothing</tt> to indicate EOF.
--   
--   Note that having received EOF it is still possible to send. The EOF
--   condition is however monotonic.
--   
--   It may raise exceptions (as appropriate for the monad and kind of
--   channel).
[recv] :: Channel m -> m (Maybe ByteString)

-- | Create a pair of <a>Channel</a>s that are connected internally.
--   
--   This is intended for inter-thread communication, such as between a
--   multiplexing thread and a thread running a peer.
--   
--   It uses lazy <tt>ByteString</tt>s but it ensures that data written to
--   the channel is <i>fully evaluated</i> first. This ensures that any
--   work to serialise the data takes place on the <i>writer side and not
--   the reader side</i>.
createBufferConnectedChannels :: forall m. MonadSTM m => m (Channel m, Channel m)

-- | Create a local pipe, with both ends in this process, and expose that
--   as a pair of <a>Channel</a>s, one for each end.
--   
--   This is primarily for testing purposes since it does not allow actual
--   IPC.
createPipeConnectedChannels :: IO (Channel IO, Channel IO)
createSocketConnectedChannels :: Family -> IO (Channel IO, Channel IO)

-- | Open a pair of Unix FIFOs, and expose that as a <a>Channel</a>.
--   
--   The peer process needs to open the same files but the other way
--   around, for writing and reading.
--   
--   This is primarily for the purpose of demonstrations that use
--   communication between multiple local processes. It is Unix specific.
withFifosAsChannel :: FilePath -> FilePath -> (Channel IO -> IO a) -> IO a

-- | Make a <a>Channel</a> from a <tt>Socket</tt>. The socket must be a
--   stream socket
socketAsChannel :: Socket -> Channel IO
channelEffect :: forall m. Monad m => (ByteString -> m ()) -> (Maybe ByteString -> m ()) -> Channel m -> Channel m

-- | Delay a channel on the receiver end.
--   
--   This is intended for testing, as a crude approximation of network
--   delays. More accurate models along these lines are of course possible.
delayChannel :: (MonadSTM m, MonadTimer m) => DiffTime -> Channel m -> Channel m

-- | Channel which logs sent and received messages.
loggingChannel :: (MonadSay m, Show id) => id -> Channel m -> Channel m

module Network.Mux.DeltaQ.TraceTypes
newtype SISec
S :: Float -> SISec
newtype SISec2
S2 :: Float -> SISec2
squareSISec :: SISec -> SISec2
instance GHC.Num.Num Network.Mux.DeltaQ.TraceTypes.SISec
instance GHC.Classes.Ord Network.Mux.DeltaQ.TraceTypes.SISec
instance GHC.Classes.Eq Network.Mux.DeltaQ.TraceTypes.SISec
instance GHC.Num.Num Network.Mux.DeltaQ.TraceTypes.SISec2
instance GHC.Classes.Ord Network.Mux.DeltaQ.TraceTypes.SISec2
instance GHC.Classes.Eq Network.Mux.DeltaQ.TraceTypes.SISec2

module Network.Mux.DeltaQ.TraceStatsSupport
estimateGS :: [(Int, SISec)] -> (Double, Double, Double)

module Network.Mux.Time

-- | This is a length of time, as measured by a clock. Conversion functions
--   will treat it as seconds. It has a precision of 10^-12 s.
data DiffTime
diffTimeToMicroseconds :: DiffTime -> Integer
microsecondsToDiffTime :: Integer -> DiffTime

-- | This is a slightly peculiar operation: it returns the number of
--   microseconds since an arbitrary epoch, modulo 2^32. This number of
--   microseconds wraps every ~35 minutes.
--   
--   The purpose is to give a compact timestamp (compact to send over the
--   wire) for measuring time differences on the order of seconds or less.
timestampMicrosecondsLow32Bits :: Time -> Word32


-- | An alternative implementation of <a>timeout</a> for platforms (i.e.
--   Windows) where the standard implementation is too expensive.
--   
--   The implementation provided here is for the special case where only
--   one timeout is active at once. A concurrent implementation would be
--   possible but is not currently needed.
module Network.Mux.Timeout

-- | The type of the <a>timeout</a> function.
type TimeoutFn m = forall a. DiffTime -> m a -> m (Maybe a)

-- | A <a>timeout</a> that is reasonably efficient for all platforms.
--   
--   On Unix it uses exactly <a>timeout</a> and on Windows it uses
--   <a>withTimeoutSerialAlternative</a>.
--   
--   <pre>
--   withTimeoutSerial $ \timeout -&gt;
--     -- now use timeout as one would use System.Timeout.timeout
--     -- but not concurrently!
--   </pre>
--   
--   The implementation has a serial constraint: the body action that calls
--   <tt>timeout</tt> can <i>only do so from one thread at once</i>.
withTimeoutSerial :: forall m b. (MonadAsync m, MonadFork m, MonadMonotonicTime m, MonadTimer m, MonadMask m, MonadThrow (STM m)) => (TimeoutFn m -> m b) -> m b

-- | This version simply passes the native platform's <a>timeout</a>.
--   
--   A <a>timeout</a> that is reasonably efficient for all platforms.
--   
--   On Unix it uses exactly <a>timeout</a> and on Windows it uses
--   <a>withTimeoutSerialAlternative</a>.
--   
--   <pre>
--   withTimeoutSerial $ \timeout -&gt;
--     -- now use timeout as one would use System.Timeout.timeout
--     -- but not concurrently!
--   </pre>
--   
--   The implementation has a serial constraint: the body action that calls
--   <tt>timeout</tt> can <i>only do so from one thread at once</i>.
withTimeoutSerialNative :: forall m b. (MonadAsync m, MonadFork m, MonadMonotonicTime m, MonadTimer m, MonadMask m, MonadThrow (STM m)) => (TimeoutFn m -> m b) -> m b

-- | An alternative implementation of <a>timeout</a> for platforms where
--   the standard implementation is too expensive.
--   
--   <pre>
--   withTimeoutSerial $ \timeout -&gt;
--     -- now use timeout as one would use System.Timeout.timeout
--     -- but not concurrently!
--   </pre>
--   
--   This implementation has a serial constraint: the body action that
--   calls <tt>timeout</tt> can <i>only do so from one thread at once</i>.
--   
--   Further details for the curious:
--   
--   the problem with <tt>System.Timeout.timeout</tt> is that (as of base
--   4.12) it has two implementations, one for Unix with the threaded RTS,
--   and one for all other configurations.
--   
--   The Unix threaded RTS implementation is rather clever and very fast.
--   In the normal case of no timeout, it only has to allocate a timer
--   entry. Only in the case the timeout occurs does it allocate a
--   <a>forkIO</a> thread to do the potentially-blocking operation of
--   sending the asynchronous exception to interrupt the action under
--   timeout.
--   
--   The implementation for all other configurations has to allocate a
--   <a>forkIO</a> thread up front, whether or not the timeout fires. This
--   is fine for many applications but not for network timers which have to
--   be created and altered/cancelled with very high frequency.
--   
--   The implementation here only relies upon <tt>threadDelay</tt> which
--   has an efficient implementation on all platforms. It uses a separate
--   monitoring thread which will throw an exception to terminate the
--   action if the timeout expires. This is why it uses the "with" style:
--   because it keeps a monitoring thread over a region of execution that
--   may use many timeouts. The cost of allocating this thread is amortised
--   over all the timeouts used.
--   
--   This implementation is simplified by the constraint that the timeouts
--   only be used serially. In addition, it has the limitation that
--   timeouts may not always be detected promptly: e.g. a 10s timeout on an
--   action that finishes immediately, followed by a 5s timeout on an
--   action will only actually be interrupted after 10s. So it's possible
--   that action with the 5s timeout runs for up to 10s. This is ok for
--   many applications provided that the variance in timeouts is not too
--   large and the timeouts don't need to be too tight.
withTimeoutSerialAlternative :: forall m b. (MonadAsync m, MonadFork m, MonadMonotonicTime m, MonadTimer m, MonadMask m, MonadThrow (STM m)) => (TimeoutFn m -> m b) -> m b
instance GHC.Show.Show Network.Mux.Timeout.TimeoutException
instance GHC.Show.Show Network.Mux.Timeout.TimeoutAssertion
instance GHC.Exception.Type.Exception Network.Mux.Timeout.TimeoutAssertion
instance GHC.Exception.Type.Exception Network.Mux.Timeout.TimeoutException

module Network.Mux.Types

-- | Application run by mux layer.
--   
--   <ul>
--   <li>enumeration of client application, e.g. a wallet application
--   communicating with a node using ChainSync and TxSubmission protocols;
--   this only requires to run client side of each protocol.</li>
--   <li>enumeration of server applications: this application type is
--   mostly useful tests.</li>
--   <li>enumeration of both client and server applications, e.g. a full
--   node serving downstream peers using server side of each protocol and
--   getting updates from upstream peers using client side of each of the
--   protocols.</li>
--   </ul>
newtype MiniProtocolBundle (mode :: MuxMode)
MiniProtocolBundle :: [MiniProtocolInfo mode] -> MiniProtocolBundle (mode :: MuxMode)
data MiniProtocolInfo (mode :: MuxMode)
MiniProtocolInfo :: !MiniProtocolNum -> !MiniProtocolDirection mode -> !MiniProtocolLimits -> MiniProtocolInfo (mode :: MuxMode)
[miniProtocolNum] :: MiniProtocolInfo (mode :: MuxMode) -> !MiniProtocolNum
[miniProtocolDir] :: MiniProtocolInfo (mode :: MuxMode) -> !MiniProtocolDirection mode
[miniProtocolLimits] :: MiniProtocolInfo (mode :: MuxMode) -> !MiniProtocolLimits

-- | The wire format includes the protocol numbers, and it's vital that
--   these are stable. They are not necessarily dense however, as new ones
--   are added and some old ones retired. So we use a dedicated class for
--   this rather than reusing <a>Enum</a>. This also covers unrecognised
--   protocol numbers on the decoding side.
newtype MiniProtocolNum
MiniProtocolNum :: Word16 -> MiniProtocolNum
data MiniProtocolDirection (mode :: MuxMode)
[InitiatorDirectionOnly] :: MiniProtocolDirection InitiatorMode
[ResponderDirectionOnly] :: MiniProtocolDirection ResponderMode
[InitiatorDirection] :: MiniProtocolDirection InitiatorResponderMode
[ResponderDirection] :: MiniProtocolDirection InitiatorResponderMode

-- | Per Miniprotocol limits
data MiniProtocolLimits
MiniProtocolLimits :: !Int -> MiniProtocolLimits

-- | Limit on the maximum number of bytes that can be queued in the
--   miniprotocol's ingress queue.
[maximumIngressQueue] :: MiniProtocolLimits -> !Int
data MuxMode
[InitiatorMode] :: MuxMode
[ResponderMode] :: MuxMode
[InitiatorResponderMode] :: MuxMode
type family HasInitiator (mode :: MuxMode) :: Bool
type family HasResponder (mode :: MuxMode) :: Bool
type IngressQueue m = StrictTVar m ByteString

-- | The index of a protocol in a MuxApplication, used for array indicies
data MiniProtocolIx
data MiniProtocolDir
InitiatorDir :: MiniProtocolDir
ResponderDir :: MiniProtocolDir
protocolDirEnum :: MiniProtocolDirection mode -> MiniProtocolDir
data MiniProtocolState mode m
MiniProtocolState :: MiniProtocolInfo mode -> IngressQueue m -> StrictTVar m MiniProtocolStatus -> MiniProtocolState mode m
[miniProtocolInfo] :: MiniProtocolState mode m -> MiniProtocolInfo mode
[miniProtocolIngressQueue] :: MiniProtocolState mode m -> IngressQueue m
[miniProtocolStatusVar] :: MiniProtocolState mode m -> StrictTVar m MiniProtocolStatus
data MiniProtocolStatus
StatusIdle :: MiniProtocolStatus
StatusStartOnDemand :: MiniProtocolStatus
StatusRunning :: MiniProtocolStatus

-- | Low level access to underlying socket or pipe. There are three smart
--   constructors:
--   
--   <ul>
--   <li><a>socketAsMuxBearer</a></li>
--   <li><a>pipeAsMuxBearer</a></li>
--   <li><pre>Test.Mux.queuesAsMuxBearer</pre></li>
--   </ul>
data MuxBearer m
MuxBearer :: (TimeoutFn m -> MuxSDU -> m Time) -> (TimeoutFn m -> m (MuxSDU, Time)) -> Word16 -> MuxBearer m

-- | Timestamp and send MuxSDU.
[write] :: MuxBearer m -> TimeoutFn m -> MuxSDU -> m Time

-- | Read a MuxSDU
[read] :: MuxBearer m -> TimeoutFn m -> m (MuxSDU, Time)

-- | Return a suitable MuxSDU payload size.
[sduSize] :: MuxBearer m -> Word16

-- | A channel which wraps each message as an <a>MuxSDU</a> using giving
--   <a>MiniProtocolNum</a> and <a>MiniProtocolDir</a>.
muxBearerAsChannel :: forall m. Functor m => MuxBearer m -> MiniProtocolNum -> MiniProtocolDir -> Channel m
data MuxSDU
MuxSDU :: !MuxSDUHeader -> !ByteString -> MuxSDU
[msHeader] :: MuxSDU -> !MuxSDUHeader
[msBlob] :: MuxSDU -> !ByteString
data MuxSDUHeader
MuxSDUHeader :: !RemoteClockModel -> !MiniProtocolNum -> !MiniProtocolDir -> !Word16 -> MuxSDUHeader
[mhTimestamp] :: MuxSDUHeader -> !RemoteClockModel
[mhNum] :: MuxSDUHeader -> !MiniProtocolNum
[mhDir] :: MuxSDUHeader -> !MiniProtocolDir
[mhLength] :: MuxSDUHeader -> !Word16
msTimestamp :: MuxSDU -> RemoteClockModel
setTimestamp :: MuxSDU -> RemoteClockModel -> MuxSDU
msNum :: MuxSDU -> MiniProtocolNum
msDir :: MuxSDU -> MiniProtocolDir
msLength :: MuxSDU -> Word16
newtype RemoteClockModel
RemoteClockModel :: Word32 -> RemoteClockModel
[unRemoteClockModel] :: RemoteClockModel -> Word32

-- | The <a>DiffTime</a> represented by a tick in the
--   <a>RemoteClockModel</a>
remoteClockPrecision :: DiffTime
instance GHC.Enum.Bounded Network.Mux.Types.RemoteClockModel
instance GHC.Classes.Eq Network.Mux.Types.RemoteClockModel
instance GHC.Show.Show Network.Mux.Types.MiniProtocolNum
instance GHC.Ix.Ix Network.Mux.Types.MiniProtocolNum
instance GHC.Enum.Enum Network.Mux.Types.MiniProtocolNum
instance GHC.Classes.Ord Network.Mux.Types.MiniProtocolNum
instance GHC.Classes.Eq Network.Mux.Types.MiniProtocolNum
instance GHC.Show.Show Network.Mux.Types.MiniProtocolIx
instance GHC.Ix.Ix Network.Mux.Types.MiniProtocolIx
instance GHC.Enum.Enum Network.Mux.Types.MiniProtocolIx
instance GHC.Num.Num Network.Mux.Types.MiniProtocolIx
instance GHC.Classes.Ord Network.Mux.Types.MiniProtocolIx
instance GHC.Classes.Eq Network.Mux.Types.MiniProtocolIx
instance GHC.Show.Show Network.Mux.Types.MiniProtocolDir
instance GHC.Enum.Bounded Network.Mux.Types.MiniProtocolDir
instance GHC.Enum.Enum Network.Mux.Types.MiniProtocolDir
instance GHC.Ix.Ix Network.Mux.Types.MiniProtocolDir
instance GHC.Classes.Ord Network.Mux.Types.MiniProtocolDir
instance GHC.Classes.Eq Network.Mux.Types.MiniProtocolDir
instance GHC.Classes.Eq Network.Mux.Types.MiniProtocolStatus
instance GHC.Classes.Eq (Network.Mux.Types.MiniProtocolDirection mode)
instance GHC.Classes.Ord (Network.Mux.Types.MiniProtocolDirection mode)

module Network.Mux.Trace

-- | Error type used in accross the mux layer.
data MuxError
MuxError :: !MuxErrorType -> !String -> MuxError
[errorType] :: MuxError -> !MuxErrorType
[errorMsg] :: MuxError -> !String

-- | Enumeration of error conditions.
data MuxErrorType

-- | returned by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxUnknownMiniProtocol :: MuxErrorType

-- | return by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxDecodeError :: MuxErrorType

-- | thrown by <a>MuxBearer</a> when received a null byte.
MuxBearerClosed :: MuxErrorType

-- | thrown by <tt>demux</tt> when violating <a>maximumIngressQueue</a>
--   byte limit.
MuxIngressQueueOverRun :: MuxErrorType

-- | thrown when data arrives on a responder channel when the mux was set
--   up as an <tt>InitiatorApp</tt>.
MuxInitiatorOnly :: MuxErrorType

-- | <a>IOException</a> thrown by
MuxIOException :: IOException -> MuxErrorType

-- | thrown when reading of a single SDU takes too long
MuxSDUReadTimeout :: MuxErrorType

-- | thrown when writing a single SDU takes too long
MuxSDUWriteTimeout :: MuxErrorType

-- | Result of runMiniProtocol's completionAction in case of an error.
MuxShutdown :: !Maybe MuxErrorType -> MuxErrorType

-- | Mux stopped by <tt>stopMux</tt>
MuxCleanShutdown :: MuxErrorType

-- | Mux blocked on <tt>completionVar</tt>.
MuxBlockedOnCompletionVar :: !MiniProtocolNum -> MuxErrorType

-- | Handler for <a>IOException</a>s which wrappes them in <a>MuxError</a>.
--   
--   It is used various <a>MuxBearer</a> implementations: *
--   <tt>socketAsMuxBearer</tt> * <tt>pipeAsMuxBearer</tt>
handleIOException :: MonadThrow m => String -> IOException -> m a

-- | Enumeration of Mux events that can be traced.
data MuxTrace
MuxTraceRecvHeaderStart :: MuxTrace
MuxTraceRecvHeaderEnd :: !MuxSDUHeader -> MuxTrace
MuxTraceRecvDeltaQObservation :: !MuxSDUHeader -> Time -> MuxTrace
MuxTraceRecvDeltaQSample :: !Double -> !Int -> !Int -> !Double -> !Double -> !Double -> !Double -> !String -> MuxTrace
MuxTraceRecvStart :: !Int -> MuxTrace
MuxTraceRecvEnd :: !Int -> MuxTrace
MuxTraceSendStart :: !MuxSDUHeader -> MuxTrace
MuxTraceSendEnd :: MuxTrace
MuxTraceState :: !MuxBearerState -> MuxTrace
MuxTraceCleanExit :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceExceptionExit :: !MiniProtocolNum -> !MiniProtocolDir -> !SomeException -> MuxTrace
MuxTraceChannelRecvStart :: !MiniProtocolNum -> MuxTrace
MuxTraceChannelRecvEnd :: !MiniProtocolNum -> !Int -> MuxTrace
MuxTraceChannelSendStart :: !MiniProtocolNum -> !Int -> MuxTrace
MuxTraceChannelSendEnd :: !MiniProtocolNum -> MuxTrace
MuxTraceHandshakeStart :: MuxTrace
MuxTraceHandshakeClientEnd :: !DiffTime -> MuxTrace
MuxTraceHandshakeServerEnd :: MuxTrace
MuxTraceHandshakeClientError :: !e -> !DiffTime -> MuxTrace
MuxTraceHandshakeServerError :: !e -> MuxTrace
MuxTraceSDUReadTimeoutException :: MuxTrace
MuxTraceSDUWriteTimeoutException :: MuxTrace
MuxTraceStartEagerly :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceStartOnDemand :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceStartedOnDemand :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceTerminating :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceShutdown :: MuxTrace
data MuxBearerState

-- | MuxBearer has successufully completed the handshake.
Mature :: MuxBearerState

-- | MuxBearer is dead and the underlying bearer has been closed.
Dead :: MuxBearerState

-- | Type used for tracing mux events.
data WithMuxBearer peerid a
WithMuxBearer :: !peerid -> !a -> WithMuxBearer peerid a

-- | A tag that should identify a specific mux bearer.
[wmbPeerId] :: WithMuxBearer peerid a -> !peerid
[wmbEvent] :: WithMuxBearer peerid a -> !a

-- | A peer label for use in <tt>Tracer</tt>s. This annotates tracer output
--   as being associated with a given peer identifier.
data TraceLabelPeer peerid a
TraceLabelPeer :: peerid -> a -> TraceLabelPeer peerid a
instance GHC.Classes.Eq Network.Mux.Trace.MuxErrorType
instance GHC.Show.Show Network.Mux.Trace.MuxErrorType
instance GHC.Show.Show Network.Mux.Trace.MuxError
instance GHC.Generics.Generic Network.Mux.Trace.MuxError
instance (GHC.Show.Show peerid, GHC.Show.Show a) => GHC.Show.Show (Network.Mux.Trace.TraceLabelPeer peerid a)
instance GHC.Base.Functor (Network.Mux.Trace.TraceLabelPeer peerid)
instance (GHC.Classes.Eq peerid, GHC.Classes.Eq a) => GHC.Classes.Eq (Network.Mux.Trace.TraceLabelPeer peerid a)
instance (GHC.Show.Show peerid, GHC.Show.Show a) => GHC.Show.Show (Network.Mux.Trace.WithMuxBearer peerid a)
instance GHC.Generics.Generic (Network.Mux.Trace.WithMuxBearer peerid a)
instance GHC.Show.Show Network.Mux.Trace.MuxBearerState
instance GHC.Classes.Eq Network.Mux.Trace.MuxBearerState
instance GHC.Show.Show Network.Mux.Trace.MuxTrace
instance GHC.Exception.Type.Exception Network.Mux.Trace.MuxError

module Network.Mux.Ingress

-- | demux runs as a single separate thread and reads complete
--   <a>MuxSDU</a>s from the underlying Mux Bearer and forwards it to the
--   matching ingress queue.
demuxer :: (MonadAsync m, MonadFork m, MonadMask m, MonadThrow (STM m), MonadTimer m, MonadTime m) => [MiniProtocolState mode m] -> MuxBearer m -> m void

module Network.Mux.Egress

-- | Process the messages from the mini protocols - there is a single
--   shared FIFO that contains the items of work. This is processed so that
--   each active demand gets a <tt>maxSDU</tt>s work of data processed each
--   time it gets to the front of the queue
muxer :: (MonadAsync m, MonadFork m, MonadMask m, MonadThrow (STM m), MonadTimer m, MonadTime m) => EgressQueue m -> MuxBearer m -> m void
type EgressQueue m = TBQueue m (TranslocationServiceRequest m)

-- | A TranslocationServiceRequest is a demand for the translocation of a
--   single mini-protocol message. This message can be of arbitrary (yet
--   bounded) size. This multiplexing layer is responsible for the
--   segmentation of concrete representation into appropriate SDU's for
--   onward transmission.
data TranslocationServiceRequest m
TLSRDemand :: !MiniProtocolNum -> !MiniProtocolDir -> !Wanton m -> TranslocationServiceRequest m

-- | A Wanton represent the concrete data to be translocated, note that the
--   TVar becoming empty indicates -- that the last fragment of the data
--   has been enqueued on the -- underlying bearer.
newtype Wanton m
Wanton :: StrictTVar m ByteString -> Wanton m
[want] :: Wanton m -> StrictTVar m ByteString

module Network.Mux.DeltaQ.TraceStats
step :: RemoteClockModel -> Time -> Int -> StatsA -> (StatsA, Maybe OneWayDeltaQSample)

-- | One way measurement for interval. Note that the fields are lazy here
--   so that only calcuation necessary to satisfy strictness of use occurs.
data OneWayDeltaQSample
OneWaySample :: Double -> Int -> Int -> Double -> Double -> Double -> Double -> String -> OneWayDeltaQSample
[duration] :: OneWayDeltaQSample -> Double
[sumPackets] :: OneWayDeltaQSample -> Int
[sumTotalSDU] :: OneWayDeltaQSample -> Int
[estDeltaQS] :: OneWayDeltaQSample -> Double
[estDeltaQVMean] :: OneWayDeltaQSample -> Double
[estDeltaQVVar] :: OneWayDeltaQSample -> Double
[estR] :: OneWayDeltaQSample -> Double
[sizeDist] :: OneWayDeltaQSample -> String
constructSample :: StatsA -> OneWayDeltaQSample

-- | Statistics accumulator. Strict evaluation used to keep the memory
--   footprint strictly bounded.
data StatsA

-- | Initial StatsA
initialStatsA :: StatsA
instance GHC.Base.Semigroup Network.Mux.DeltaQ.TraceStats.PerSizeRecord

module Network.Mux.DeltaQ.TraceTransformer

-- | Create a trace transformer that will emit
--   <a>MuxTraceRecvDeltaQSample</a> no more frequently than every 10
--   seconds (when in use).
initDeltaQTracer :: MonadSTM m => m (Tracer m MuxTrace -> Tracer m MuxTrace)
initDeltaQTracer' :: MonadSTM m => Tracer m MuxTrace -> m (Tracer m MuxTrace)

module Network.Mux.Codec

-- | Encode a <a>MuxSDU</a> as a <tt>ByteString</tt>.
--   
--   <pre>
--   Binary format used by 'encodeMuxSDU' and 'decodeMuxSDUHeader'
--    0                   1                   2                   3
--    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
--   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--   |              transmission time                                |
--   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--   |M|    conversation id          |              length           |
--   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
--   </pre>
--   
--   All fields are in big endian byteorder.
encodeMuxSDU :: MuxSDU -> ByteString

-- | Decode a <tt>MuSDU</tt> header. A left inverse of <a>encodeMuxSDU</a>.
decodeMuxSDU :: ByteString -> Either MuxError MuxSDU

module Network.Mux
newMux :: MonadSTM m => MiniProtocolBundle mode -> m (Mux mode m)
data Mux (mode :: MuxMode) m
data MuxMode
[InitiatorMode] :: MuxMode
[ResponderMode] :: MuxMode
[InitiatorResponderMode] :: MuxMode
type family HasInitiator (mode :: MuxMode) :: Bool
type family HasResponder (mode :: MuxMode) :: Bool

-- | Application run by mux layer.
--   
--   <ul>
--   <li>enumeration of client application, e.g. a wallet application
--   communicating with a node using ChainSync and TxSubmission protocols;
--   this only requires to run client side of each protocol.</li>
--   <li>enumeration of server applications: this application type is
--   mostly useful tests.</li>
--   <li>enumeration of both client and server applications, e.g. a full
--   node serving downstream peers using server side of each protocol and
--   getting updates from upstream peers using client side of each of the
--   protocols.</li>
--   </ul>
newtype MiniProtocolBundle (mode :: MuxMode)
MiniProtocolBundle :: [MiniProtocolInfo mode] -> MiniProtocolBundle (mode :: MuxMode)
data MiniProtocolInfo (mode :: MuxMode)
MiniProtocolInfo :: !MiniProtocolNum -> !MiniProtocolDirection mode -> !MiniProtocolLimits -> MiniProtocolInfo (mode :: MuxMode)
[miniProtocolNum] :: MiniProtocolInfo (mode :: MuxMode) -> !MiniProtocolNum
[miniProtocolDir] :: MiniProtocolInfo (mode :: MuxMode) -> !MiniProtocolDirection mode
[miniProtocolLimits] :: MiniProtocolInfo (mode :: MuxMode) -> !MiniProtocolLimits

-- | The wire format includes the protocol numbers, and it's vital that
--   these are stable. They are not necessarily dense however, as new ones
--   are added and some old ones retired. So we use a dedicated class for
--   this rather than reusing <a>Enum</a>. This also covers unrecognised
--   protocol numbers on the decoding side.
newtype MiniProtocolNum
MiniProtocolNum :: Word16 -> MiniProtocolNum
data MiniProtocolDirection (mode :: MuxMode)
[InitiatorDirectionOnly] :: MiniProtocolDirection InitiatorMode
[ResponderDirectionOnly] :: MiniProtocolDirection ResponderMode
[InitiatorDirection] :: MiniProtocolDirection InitiatorResponderMode
[ResponderDirection] :: MiniProtocolDirection InitiatorResponderMode

-- | Per Miniprotocol limits
data MiniProtocolLimits
MiniProtocolLimits :: !Int -> MiniProtocolLimits

-- | Limit on the maximum number of bytes that can be queued in the
--   miniprotocol's ingress queue.
[maximumIngressQueue] :: MiniProtocolLimits -> !Int

-- | runMux starts a mux bearer for the specified protocols corresponding
--   to one of the provided Versions.
--   
--   <b>Isometric flow control: analysis of head-of-line blocking of the
--   ingress side of the multiplexer</b>
--   
--   For each mini-protocol (enumeratated by <tt>ptcl</tt>), mux will
--   create two channels. One for initiator and one for the responder. Each
--   channel will use a single <a>Wanton</a>. When it is filled, it is put
--   in a common queue <tt>tsrQueue</tt>. This means that the queue is
--   bound by <tt>2 * |ptcl|</tt>. Every side of a mini-protocol is served
--   by a single <a>Wanton</a>: when an applicaiton sends data, the channel
--   will try to put it into the <a>Wanton</a> (which might block).
--   <a>Wanton</a>s are taken from the <tt>tsrQueue</tt> queue by one of
--   mux threads. This elimnates head of line blocking: each mini-protocol
--   thread can block on puting more bytes into its <a>Wanton</a>, but it
--   cannot block the other mini-protocols or the thread that is reading
--   the <tt>tsrQueue</tt> queue. This is ensured since the
--   <a>muxChannel</a> will put only a non-empty <a>Wanton</a> to the
--   <tt>tsrQueue</tt> queue, and on such wantons the queue is never
--   blocked. This means that the only way the queue can block is when its
--   empty, which means that none of the mini-protocols wanted to send. The
--   egress part will read a <a>Wanton</a>, take a fixed amount of bytes
--   encode them in as an <a>MuxSDU</a>; if there are leftovers it will put
--   them back in the <a>Wanton</a> and place it at the end of the queue
--   (reading and writting to it will happen in a single STM transaction
--   which assures that the order of requests from a mini-protocol is
--   preserved.
--   
--   Properties:
--   
--   <ul>
--   <li>at any given time the <tt>tsrQueue</tt> contains at most one
--   <a>TranslocationServiceRequest</a> from a given mini-protocol of the
--   given <a>MiniProtocolDir</a>, thus the queue contains at most <tt>2 *
--   |ptcl|</tt> translocation requests.</li>
--   <li>at any given time each <tt>TranslocationServiceRequest</tt>
--   contains a non-empty <a>Wanton</a></li>
--   </ul>
runMux :: forall m mode. (MonadAsync m, MonadCatch m, MonadFork m, MonadThrow (STM m), MonadTime m, MonadTimer m, MonadMask m) => Tracer m MuxTrace -> Mux mode m -> MuxBearer m -> m ()

-- | Low level access to underlying socket or pipe. There are three smart
--   constructors:
--   
--   <ul>
--   <li><a>socketAsMuxBearer</a></li>
--   <li><a>pipeAsMuxBearer</a></li>
--   <li><pre>Test.Mux.queuesAsMuxBearer</pre></li>
--   </ul>
data MuxBearer m

-- | Arrange to run a protocol thread (for a particular
--   <a>MiniProtocolNum</a> and <a>MiniProtocolDirection</a>) to interact
--   on this protocol's <a>Channel</a>.
--   
--   The protocol thread can either be started eagerly or on-demand:
--   
--   <ul>
--   <li>With <a>StartEagerly</a>, the thread is started promptly. This is
--   appropriate for mini-protocols where the opening message may be sent
--   by this thread.</li>
--   <li>With <a>StartOnDemand</a>, the thread is not started until the
--   first data is received for this mini-protocol. This is appropriate for
--   mini-protocols where the opening message is sent by the remote
--   peer.</li>
--   </ul>
--   
--   The result is a STM action to block and wait on the protocol
--   completion. It is safe to call this completion action multiple times:
--   it will always return the same result once the protocol thread
--   completes. Incase the Mux has stopped, either due to an exception or
--   because of a call to muxStop a `Left MuxError` will be returned from
--   the STM action.
--   
--   It is an error to start a new protocol thread while one is still
--   running, for the same <a>MiniProtocolNum</a> and
--   <a>MiniProtocolDirection</a>. This can easily be avoided by using the
--   STM completion action to wait for the previous one to finish.
--   
--   It is safe to ask to start a protocol thread before <a>runMux</a>. In
--   this case the protocol thread will not actually start until
--   <a>runMux</a> is called, irrespective of the
--   <a>StartOnDemandOrEagerly</a> value.
runMiniProtocol :: forall mode m a. MonadSTM m => Mux mode m -> MiniProtocolNum -> MiniProtocolDirection mode -> StartOnDemandOrEagerly -> (Channel m -> m (a, Maybe ByteString)) -> m (STM m (Either SomeException a))
data StartOnDemandOrEagerly
StartOnDemand :: StartOnDemandOrEagerly
StartEagerly :: StartOnDemandOrEagerly

-- | Shut down the mux. This will cause <a>runMux</a> to return. It does
--   not wait for any protocol threads to finish, so you should do that
--   first if necessary.
stopMux :: MonadSTM m => Mux mode m -> m ()

-- | Error type used in accross the mux layer.
data MuxError
MuxError :: !MuxErrorType -> !String -> MuxError
[errorType] :: MuxError -> !MuxErrorType
[errorMsg] :: MuxError -> !String

-- | Enumeration of error conditions.
data MuxErrorType

-- | returned by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxUnknownMiniProtocol :: MuxErrorType

-- | return by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxDecodeError :: MuxErrorType

-- | thrown by <a>MuxBearer</a> when received a null byte.
MuxBearerClosed :: MuxErrorType

-- | thrown by <tt>demux</tt> when violating <a>maximumIngressQueue</a>
--   byte limit.
MuxIngressQueueOverRun :: MuxErrorType

-- | thrown when data arrives on a responder channel when the mux was set
--   up as an <tt>InitiatorApp</tt>.
MuxInitiatorOnly :: MuxErrorType

-- | <a>IOException</a> thrown by
MuxIOException :: IOException -> MuxErrorType

-- | thrown when reading of a single SDU takes too long
MuxSDUReadTimeout :: MuxErrorType

-- | thrown when writing a single SDU takes too long
MuxSDUWriteTimeout :: MuxErrorType

-- | Result of runMiniProtocol's completionAction in case of an error.
MuxShutdown :: !Maybe MuxErrorType -> MuxErrorType

-- | Mux stopped by <tt>stopMux</tt>
MuxCleanShutdown :: MuxErrorType

-- | Mux blocked on <tt>completionVar</tt>.
MuxBlockedOnCompletionVar :: !MiniProtocolNum -> MuxErrorType
traceMuxBearerState :: Tracer m MuxTrace -> MuxBearerState -> m ()
data MuxBearerState

-- | MuxBearer has successufully completed the handshake.
Mature :: MuxBearerState

-- | MuxBearer is dead and the underlying bearer has been closed.
Dead :: MuxBearerState

-- | Enumeration of Mux events that can be traced.
data MuxTrace
MuxTraceRecvHeaderStart :: MuxTrace
MuxTraceRecvHeaderEnd :: !MuxSDUHeader -> MuxTrace
MuxTraceRecvDeltaQObservation :: !MuxSDUHeader -> Time -> MuxTrace
MuxTraceRecvDeltaQSample :: !Double -> !Int -> !Int -> !Double -> !Double -> !Double -> !Double -> !String -> MuxTrace
MuxTraceRecvStart :: !Int -> MuxTrace
MuxTraceRecvEnd :: !Int -> MuxTrace
MuxTraceSendStart :: !MuxSDUHeader -> MuxTrace
MuxTraceSendEnd :: MuxTrace
MuxTraceState :: !MuxBearerState -> MuxTrace
MuxTraceCleanExit :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceExceptionExit :: !MiniProtocolNum -> !MiniProtocolDir -> !SomeException -> MuxTrace
MuxTraceChannelRecvStart :: !MiniProtocolNum -> MuxTrace
MuxTraceChannelRecvEnd :: !MiniProtocolNum -> !Int -> MuxTrace
MuxTraceChannelSendStart :: !MiniProtocolNum -> !Int -> MuxTrace
MuxTraceChannelSendEnd :: !MiniProtocolNum -> MuxTrace
MuxTraceHandshakeStart :: MuxTrace
MuxTraceHandshakeClientEnd :: !DiffTime -> MuxTrace
MuxTraceHandshakeServerEnd :: MuxTrace
MuxTraceHandshakeClientError :: !e -> !DiffTime -> MuxTrace
MuxTraceHandshakeServerError :: !e -> MuxTrace
MuxTraceSDUReadTimeoutException :: MuxTrace
MuxTraceSDUWriteTimeoutException :: MuxTrace
MuxTraceStartEagerly :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceStartOnDemand :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceStartedOnDemand :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceTerminating :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceShutdown :: MuxTrace

-- | Type used for tracing mux events.
data WithMuxBearer peerid a
WithMuxBearer :: !peerid -> !a -> WithMuxBearer peerid a

-- | A tag that should identify a specific mux bearer.
[wmbPeerId] :: WithMuxBearer peerid a -> !peerid
[wmbEvent] :: WithMuxBearer peerid a -> !a
instance GHC.Classes.Eq Network.Mux.StartOnDemandOrEagerly

module Network.Mux.Compat
muxStart :: forall m mode a b. (MonadAsync m, MonadFork m, MonadThrow (STM m), MonadTime m, MonadTimer m, MonadMask m) => Tracer m MuxTrace -> MuxApplication mode m a b -> MuxBearer m -> m ()

-- | Low level access to underlying socket or pipe. There are three smart
--   constructors:
--   
--   <ul>
--   <li><a>socketAsMuxBearer</a></li>
--   <li><a>pipeAsMuxBearer</a></li>
--   <li><pre>Test.Mux.queuesAsMuxBearer</pre></li>
--   </ul>
data MuxBearer m
data MuxMode
[InitiatorMode] :: MuxMode
[ResponderMode] :: MuxMode
[InitiatorResponderMode] :: MuxMode
type family HasInitiator (mode :: MuxMode) :: Bool
type family HasResponder (mode :: MuxMode) :: Bool
newtype MuxApplication (mode :: MuxMode) m a b
MuxApplication :: [MuxMiniProtocol mode m a b] -> MuxApplication (mode :: MuxMode) m a b
data MuxMiniProtocol (mode :: MuxMode) m a b
MuxMiniProtocol :: !MiniProtocolNum -> !MiniProtocolLimits -> !RunMiniProtocol mode m a b -> MuxMiniProtocol (mode :: MuxMode) m a b
[miniProtocolNum] :: MuxMiniProtocol (mode :: MuxMode) m a b -> !MiniProtocolNum
[miniProtocolLimits] :: MuxMiniProtocol (mode :: MuxMode) m a b -> !MiniProtocolLimits
[miniProtocolRun] :: MuxMiniProtocol (mode :: MuxMode) m a b -> !RunMiniProtocol mode m a b
data RunMiniProtocol (mode :: MuxMode) m a b
[InitiatorProtocolOnly] :: (Channel m -> m (a, Maybe ByteString)) -> RunMiniProtocol InitiatorMode m a Void
[ResponderProtocolOnly] :: (Channel m -> m (b, Maybe ByteString)) -> RunMiniProtocol ResponderMode m Void b
[InitiatorAndResponderProtocol] :: (Channel m -> m (a, Maybe ByteString)) -> (Channel m -> m (b, Maybe ByteString)) -> RunMiniProtocol InitiatorResponderMode m a b

-- | The wire format includes the protocol numbers, and it's vital that
--   these are stable. They are not necessarily dense however, as new ones
--   are added and some old ones retired. So we use a dedicated class for
--   this rather than reusing <a>Enum</a>. This also covers unrecognised
--   protocol numbers on the decoding side.
newtype MiniProtocolNum
MiniProtocolNum :: Word16 -> MiniProtocolNum

-- | Per Miniprotocol limits
data MiniProtocolLimits
MiniProtocolLimits :: !Int -> MiniProtocolLimits

-- | Limit on the maximum number of bytes that can be queued in the
--   miniprotocol's ingress queue.
[maximumIngressQueue] :: MiniProtocolLimits -> !Int
data MiniProtocolDir
InitiatorDir :: MiniProtocolDir
ResponderDir :: MiniProtocolDir

-- | Error type used in accross the mux layer.
data MuxError
MuxError :: !MuxErrorType -> !String -> MuxError
[errorType] :: MuxError -> !MuxErrorType
[errorMsg] :: MuxError -> !String

-- | Enumeration of error conditions.
data MuxErrorType

-- | returned by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxUnknownMiniProtocol :: MuxErrorType

-- | return by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxDecodeError :: MuxErrorType

-- | thrown by <a>MuxBearer</a> when received a null byte.
MuxBearerClosed :: MuxErrorType

-- | thrown by <tt>demux</tt> when violating <a>maximumIngressQueue</a>
--   byte limit.
MuxIngressQueueOverRun :: MuxErrorType

-- | thrown when data arrives on a responder channel when the mux was set
--   up as an <tt>InitiatorApp</tt>.
MuxInitiatorOnly :: MuxErrorType

-- | <a>IOException</a> thrown by
MuxIOException :: IOException -> MuxErrorType

-- | thrown when reading of a single SDU takes too long
MuxSDUReadTimeout :: MuxErrorType

-- | thrown when writing a single SDU takes too long
MuxSDUWriteTimeout :: MuxErrorType

-- | Result of runMiniProtocol's completionAction in case of an error.
MuxShutdown :: !Maybe MuxErrorType -> MuxErrorType

-- | Mux stopped by <tt>stopMux</tt>
MuxCleanShutdown :: MuxErrorType

-- | Mux blocked on <tt>completionVar</tt>.
MuxBlockedOnCompletionVar :: !MiniProtocolNum -> MuxErrorType
traceMuxBearerState :: Tracer m MuxTrace -> MuxBearerState -> m ()
data MuxBearerState

-- | MuxBearer has successufully completed the handshake.
Mature :: MuxBearerState

-- | MuxBearer is dead and the underlying bearer has been closed.
Dead :: MuxBearerState

-- | Enumeration of Mux events that can be traced.
data MuxTrace
MuxTraceRecvHeaderStart :: MuxTrace
MuxTraceRecvHeaderEnd :: !MuxSDUHeader -> MuxTrace
MuxTraceRecvDeltaQObservation :: !MuxSDUHeader -> Time -> MuxTrace
MuxTraceRecvDeltaQSample :: !Double -> !Int -> !Int -> !Double -> !Double -> !Double -> !Double -> !String -> MuxTrace
MuxTraceRecvStart :: !Int -> MuxTrace
MuxTraceRecvEnd :: !Int -> MuxTrace
MuxTraceSendStart :: !MuxSDUHeader -> MuxTrace
MuxTraceSendEnd :: MuxTrace
MuxTraceState :: !MuxBearerState -> MuxTrace
MuxTraceCleanExit :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceExceptionExit :: !MiniProtocolNum -> !MiniProtocolDir -> !SomeException -> MuxTrace
MuxTraceChannelRecvStart :: !MiniProtocolNum -> MuxTrace
MuxTraceChannelRecvEnd :: !MiniProtocolNum -> !Int -> MuxTrace
MuxTraceChannelSendStart :: !MiniProtocolNum -> !Int -> MuxTrace
MuxTraceChannelSendEnd :: !MiniProtocolNum -> MuxTrace
MuxTraceHandshakeStart :: MuxTrace
MuxTraceHandshakeClientEnd :: !DiffTime -> MuxTrace
MuxTraceHandshakeServerEnd :: MuxTrace
MuxTraceHandshakeClientError :: !e -> !DiffTime -> MuxTrace
MuxTraceHandshakeServerError :: !e -> MuxTrace
MuxTraceSDUReadTimeoutException :: MuxTrace
MuxTraceSDUWriteTimeoutException :: MuxTrace
MuxTraceStartEagerly :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceStartOnDemand :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceStartedOnDemand :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceTerminating :: !MiniProtocolNum -> !MiniProtocolDir -> MuxTrace
MuxTraceShutdown :: MuxTrace

-- | Type used for tracing mux events.
data WithMuxBearer peerid a
WithMuxBearer :: !peerid -> !a -> WithMuxBearer peerid a

-- | A tag that should identify a specific mux bearer.
[wmbPeerId] :: WithMuxBearer peerid a -> !peerid
[wmbEvent] :: WithMuxBearer peerid a -> !a

module Network.Mux.Bearer.Socket

-- | Create <tt><a>MuxBearer</a></tt> from a socket.
--   
--   On Windows <a>Async</a> operations are used to read and write from a
--   socket. This means that the socket must be associated with the I/O
--   completion port with <a>associateWithIOCompletionPort</a>.
--   
--   Note: <tt>IOException</tt>s thrown by <tt>sendAll</tt> and
--   <tt>recv</tt> are wrapped in <tt>MuxError</tt>.
socketAsMuxBearer :: DiffTime -> Tracer IO MuxTrace -> Socket -> MuxBearer IO

module Network.Mux.Bearer.Queues
queuesAsMuxBearer :: forall m. (MonadSTM m, MonadTime m, MonadThrow m) => Tracer m MuxTrace -> TBQueue m ByteString -> TBQueue m ByteString -> Word16 -> MuxBearer m

module Network.Mux.Bearer.Pipe

-- | Abstraction over various types of handles. We provide two instances:
--   
--   <ul>
--   <li>based on <a>Handle</a>: os independepnt, but will not work well on
--   Windows,</li>
--   <li>based on <a>HANDLE</a>: Windows specific.</li>
--   </ul>
data PipeChannel
PipeChannel :: (Int -> IO ByteString) -> (ByteString -> IO ()) -> PipeChannel
[readHandle] :: PipeChannel -> Int -> IO ByteString
[writeHandle] :: PipeChannel -> ByteString -> IO ()
pipeChannelFromHandles :: Handle -> Handle -> PipeChannel
pipeAsMuxBearer :: Tracer IO MuxTrace -> PipeChannel -> MuxBearer IO
