HORIZON HASKELLDocslts/ghc-9.14.xd82dee82026-10-12Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · d82dee8 · 2026-10-12

Modulenetwork-mux-0.11.0.0Haskell2010

Network.Mux

Network multiplexer API.

The module should be imported qualified.

  • 23 types
  • 1 class
  • 13 values

Defining Mux protocol bundles

9 declarations
datadata Mux (mode :: Mode) (m :: Type -> Type)
#

Mux handle which allows to control the multiplexer, e.g.

  • run: run the multiplexer

  • runMiniProtocol: start a mini-protocol (eagerly or lazily)

  • stop: stop the multiplexer, causing run to return.

datadata Mode where
#

Statically configured multiplexer mode.

Constructors

  • InitiatorMode :: Mode

    Only execute initiator protocols. In this mode the multiplexer will only run its egress side.

  • ResponderMode :: Mode

    Only execute responder protocols. It this mode the multiplexer will only run its ingress side.

  • InitiatorResponderMode :: Mode

    Execute initiator and responder protocols. In this mode the multiplexer will run both ingress and egress sides.

datadata MiniProtocolInfo (mode :: Mode)
#

A static description of a mini-protocol.

Constructors

Instances1Show
newtypenewtype MiniProtocolNum
#

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 Enum. This also covers unrecognised protocol numbers on the decoding side.

Instances5Enum, Eq, Ord, Show, Ix
datadata MiniProtocolDirection (mode :: Mode) where
#
Instances3Eq, Ord, Show

Running the Mux

2 declarations
valuerun
  1. :: (MonadAsync m, MonadDelay m, MonadEvaluate m, MonadFork m, MonadLabelledSTM m, Alternative (STM m), MonadThrow (STM m), MonadTimer m, MonadMask m)
  2. => Mux mode m
  3. -> Bearer m
  4. -> m ()
#

run starts a mux bearer for the specified protocols corresponding to one of the provided Versions.

Isometric flow control: analysis of head-of-line blocking of the ingress side of the multiplexer

For each mini-protocol (enumerated by ptcl), mux will create two channels. One for initiator and one for the responder. Each channel will use a single Wanton. When it is filled, it is put in a common queue tsrQueue. This means that the queue is bound by 2 * |ptcl|. Every side of a mini-protocol is served by a single Wanton: when an application sends data, the channel will try to put it into the Wanton (which might block). Wantons are taken from the tsrQueue queue by one of mux threads. This eliminates head of line blocking: each mini-protocol thread can block on putting more bytes into its Wanton, but it cannot block the other mini-protocols or the thread that is reading the tsrQueue queue. This is ensured since the muxChannel will put only a non-empty Wanton to the tsrQueue 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 Wanton, take a fixed amount of bytes encode them in as an MuxSDU; if there are leftovers it will put them back in the Wanton and place it at the end of the queue (reading and writing to it will happen in a single STM transaction which assures that the order of requests from a mini-protocol is preserved.

Properties:

  • at any given time the tsrQueue contains at most one TranslocationServiceRequest from a given mini-protocol of the given MiniProtocolDir, thus the queue contains at most 2 * |ptcl| translocation requests.

  • at any given time each TranslocationServiceRequest contains a non-empty Wanton

valuestop :: MonadSTM m => Mux mode m -> m ()
#

Shut down the mux. This will cause run to return. It does not wait for any protocol threads to finish, so you should do that first if necessary.

Run a mini-protocol

Arrange to run a protocol thread (for a particular MiniProtocolNum and MiniProtocolDirection) to interact on this protocol's Channel.

The protocol thread can either be started eagerly or on-demand:

  • With StartEagerly, the thread is started promptly. This is appropriate for mini-protocols where the opening message may be sent by this thread.

  • With StartOnDemand, 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.

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. In case the Mux has stopped, either due to an exception or because of a call to muxStop a `Left Error` 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 MiniProtocolNum and MiniProtocolDirection. 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 run. In this case the protocol thread will not actually start until run is called, irrespective of the StartOnDemandOrEagerly value.

Strategy how to start a mini-protocol.

Constructors

Instances2Eq, Show
datadata Channel (m :: Type -> Type) a
#

A channel which can send and receive values.

It is more general than what `network-mux` requires, see ByteChannel instead. However this is useful for testing purposes when one is either using mux or connecting two ends directly.

Constructors

  • Channel
    • send :: a -> m ()

      Write bytes to the channel.

      It maybe raise exceptions.

    • recv :: m (Maybe a)

      Read some input from the channel, or Nothing 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).

Bearer

5 declarations
datadata Bearer (m :: Type -> Type)
#

Low level access to underlying socket or pipe. There are three smart constructors:

  • Network.Socket.socketAsBearer

  • Network.Pipe.pipeAsBearer

  • Test.Mux.queuesAsBearer
datadata ReadBuffer (m :: Type -> Type)
#

ReadBuffer for Mux Bearers

This is used to read more data than whats currently needed in one syscall. Any extra data read is cached in rbVar until the next read request.

newtypenewtype SDUSize
#

Constructors

Instances9Enum, Eq, Integral, Num, Ord, Real, …

Monitoring

2 declarations

Errors

2 declarations
datadata Error
#

Enumeration of error conditions.

Constructors

Instances2Show, Exception
  • Show ErrorDefined in network-mux-0.11.0.0 · Network.Mux.Trace
  • Exception ErrorDefined in network-mux-0.11.0.0 · Network.Mux.Trace

Tracing

16 declarations
datadata Trace
#
Instances1Show
  • Show TraceDefined in network-mux-0.11.0.0 · Network.Mux.Trace
datadata BearerTrace
#
Instances1Show
datadata State
#

Constructors

  • Mature

    `Mux started ingress, and egress threads

  • Dead

    Mux is being shutdown.

Instances2Eq, Show
  • Eq StateDefined in network-mux-0.11.0.0 · Network.Mux.Trace
  • Show StateDefined in network-mux-0.11.0.0 · Network.Mux.Trace
datadata WithBearer peerid a
#

Type used for tracing mux events.

Constructors

Instances3Show, Generic, Rep