| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Network.Mux
Description
Network multiplexer API.
The module should be imported qualified.
Synopsis
- new :: forall (mode :: Mode) m. MonadLabelledSTM m => Tracers m -> [MiniProtocolInfo mode] -> m (Mux mode m)
- data Mux (mode :: Mode) (m :: Type -> Type)
- data Mode where
- type family HasInitiator (mode :: Mode) :: Bool where ...
- type family HasResponder (mode :: Mode) :: Bool where ...
- data MiniProtocolInfo (mode :: Mode) = MiniProtocolInfo {}
- newtype MiniProtocolNum = MiniProtocolNum Word16
- data MiniProtocolDirection (mode :: Mode) where
- newtype MiniProtocolLimits = MiniProtocolLimits {}
- run :: forall m (mode :: Mode). (MonadAsync m, MonadDelay m, MonadFork m, MonadLabelledSTM m, Alternative (STM m), MonadThrow (STM m), MonadTimer m, MonadMask m) => Mux mode m -> Bearer m -> m ()
- stop :: forall m (mode :: Mode). MonadSTM m => Mux mode m -> m ()
- runMiniProtocol :: forall (mode :: Mode) m a. (Alternative (STM m), MonadSTM m, MonadThrow m, MonadThrow (STM m)) => Mux mode m -> MiniProtocolNum -> MiniProtocolDirection mode -> StartOnDemandOrEagerly -> (ByteChannel m -> m (a, Maybe ByteString)) -> m (STM m (Either SomeException a))
- data StartOnDemandOrEagerly
- type ByteChannel (m :: Type -> Type) = Channel m ByteString
- data Channel (m :: Type -> Type) a = Channel {}
- data Bearer (m :: Type -> Type)
- newtype MakeBearer (m :: Type -> Type) fd = MakeBearer {
- getBearer :: MakeBearerCb m fd
- newtype SDUSize = SDUSize {
- getSDUSize :: Word16
- miniProtocolStateMap :: forall (m :: Type -> Type) (mode :: Mode). MonadSTM m => Mux mode m -> Map (MiniProtocolNum, MiniProtocolDir) (STM m MiniProtocolStatus)
- stopped :: forall (m :: Type -> Type) (mode :: Mode). MonadSTM m => Mux mode m -> STM m (Maybe SomeException)
- data Error
- data RuntimeError
- data Tracers' (m :: Type -> Type) (f :: Type -> Type) where
- Tracers {
- tracer :: Tracer m (f Trace)
- channelTracer :: Tracer m (f ChannelTrace)
- bearerTracer :: Tracer m (f BearerTrace)
- pattern TracersI :: Tracer m Trace -> Tracer m ChannelTrace -> Tracer m BearerTrace -> Tracers m
- Tracers {
- type Tracers (m :: Type -> Type) = Tracers' m Identity
- nullTracers :: forall (m :: Type -> Type) (f :: Type -> Type). Applicative m => Tracers' m f
- contramapTracers' :: forall f' f (m :: Type -> Type). (forall x. f' x -> f x) -> Tracers' m f -> Tracers' m f'
- data Trace
- = TraceState State
- | TraceCleanExit MiniProtocolNum MiniProtocolDir
- | TraceExceptionExit MiniProtocolNum MiniProtocolDir SomeException
- | TraceStartEagerly MiniProtocolNum MiniProtocolDir
- | TraceStartOnDemand MiniProtocolNum MiniProtocolDir
- | TraceStartOnDemandAny MiniProtocolNum MiniProtocolDir
- | TraceStartedOnDemand MiniProtocolNum MiniProtocolDir
- | TraceTerminating MiniProtocolNum MiniProtocolDir
- | TraceNewMux [MiniProtocolInfo mode]
- | TraceStarting
- | TraceStopping
- | TraceStopped
- data BearerTrace
- = TraceRecvHeaderStart
- | TraceRecvHeaderEnd SDUHeader
- | TraceRecvDeltaQObservation SDUHeader Time
- | TraceRecvDeltaQSample Double Int Int Double Double Double Double String
- | TraceEmitDeltaQ
- | TraceRecvRaw Int
- | TraceRecvStart Int
- | TraceRecvEnd Int
- | TraceSendStart SDUHeader
- | TraceSendEnd
- | TraceSDUReadTimeoutException
- | TraceSDUWriteTimeoutException
- | TraceTCPInfo StructTCPInfo Word16
- data ChannelTrace
- data State
- traceBearerState :: Tracer m Trace -> State -> m ()
- data WithBearer peerid a = WithBearer {}
- type TracersWithBearer connId (m :: Type -> Type) = Tracers' m (WithBearer connId)
- tracersWithBearer :: forall peerId (m :: Type -> Type). peerId -> TracersWithBearer peerId m -> Tracers m
Defining Mux protocol bundles
Arguments
| :: forall (mode :: Mode) m. MonadLabelledSTM m | |
| => Tracers m | |
| -> [MiniProtocolInfo mode] | description of protocols run by the mux layer. Only these protocols one will be able to execute. |
| -> m (Mux mode m) |
Create a mux handle in Mode and register mini-protocols.
data Mux (mode :: Mode) (m :: Type -> Type) Source #
Mux handle which allows to control the multiplexer, e.g.
run: run the multiplexerrunMiniProtocol: start a mini-protocol (eagerly or lazily)stop: stop the multiplexer, causingrunto return.
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. |
type family HasInitiator (mode :: Mode) :: Bool where ... Source #
Equations
| HasInitiator 'InitiatorMode = 'True | |
| HasInitiator 'ResponderMode = 'False | |
| HasInitiator 'InitiatorResponderMode = 'True |
type family HasResponder (mode :: Mode) :: Bool where ... Source #
Equations
| HasResponder 'InitiatorMode = 'False | |
| HasResponder 'ResponderMode = 'True | |
| HasResponder 'InitiatorResponderMode = 'True |
data MiniProtocolInfo (mode :: Mode) Source #
A static description of a mini-protocol.
Constructors
| MiniProtocolInfo | |
Fields
| |
Instances
| Show (MiniProtocolInfo mode) Source # | |
Defined in Network.Mux.Types Methods showsPrec :: Int -> MiniProtocolInfo mode -> ShowS # show :: MiniProtocolInfo mode -> String # showList :: [MiniProtocolInfo mode] -> ShowS # | |
newtype MiniProtocolNum Source #
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.
Constructors
| MiniProtocolNum Word16 |
Instances
data MiniProtocolDirection (mode :: Mode) where Source #
Constructors
Instances
newtype MiniProtocolLimits Source #
Per Miniprotocol limits
Constructors
| MiniProtocolLimits | |
Fields
| |
Instances
| Show MiniProtocolLimits Source # | |
Defined in Network.Mux.Types Methods showsPrec :: Int -> MiniProtocolLimits -> ShowS # show :: MiniProtocolLimits -> String # showList :: [MiniProtocolLimits] -> ShowS # | |
Running the Mux
run :: forall m (mode :: Mode). (MonadAsync m, MonadDelay m, MonadFork m, MonadLabelledSTM m, Alternative (STM m), MonadThrow (STM m), MonadTimer m, MonadMask m) => Mux mode m -> Bearer m -> m () Source #
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
tsrQueuecontains at most oneTranslocationServiceRequestfrom a given mini-protocol of the givenMiniProtocolDir, thus the queue contains at most2 * |ptcl|translocation requests. - at any given time each
TranslocationServiceRequestcontains a non-emptyWanton
stop :: forall m (mode :: Mode). MonadSTM m => Mux mode m -> m () Source #
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
runMiniProtocol :: forall (mode :: Mode) m a. (Alternative (STM m), MonadSTM m, MonadThrow m, MonadThrow (STM m)) => Mux mode m -> MiniProtocolNum -> MiniProtocolDirection mode -> StartOnDemandOrEagerly -> (ByteChannel m -> m (a, Maybe ByteString)) -> m (STM m (Either SomeException a)) Source #
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.
data StartOnDemandOrEagerly Source #
Strategy how to start a mini-protocol.
Constructors
| StartEagerly | Start a mini-protocol promptly. |
| StartOnDemand | Start a mini-protocol when data is received for the given mini-protocol. Must be used only when initial message is sent by the remote side. |
| StartOnDemandAny | Like |
Instances
| Show StartOnDemandOrEagerly Source # | |
Defined in Network.Mux.Types Methods showsPrec :: Int -> StartOnDemandOrEagerly -> ShowS # show :: StartOnDemandOrEagerly -> String # showList :: [StartOnDemandOrEagerly] -> ShowS # | |
| Eq StartOnDemandOrEagerly Source # | |
Defined in Network.Mux.Types Methods (==) :: StartOnDemandOrEagerly -> StartOnDemandOrEagerly -> Bool # (/=) :: StartOnDemandOrEagerly -> StartOnDemandOrEagerly -> Bool # | |
type ByteChannel (m :: Type -> Type) = Channel m ByteString Source #
Channel using ByteString.
data Channel (m :: Type -> Type) a Source #
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 | |
Fields
| |
Bearer
data Bearer (m :: Type -> Type) Source #
Low level access to underlying socket or pipe. There are three smart constructors:
socketAsBearerpipeAsBearerTest.Mux.queuesAsBearer
newtype MakeBearer (m :: Type -> Type) fd Source #
Construct a bearer using a MakeBearerCb.
Constructors
| MakeBearer | |
Fields
| |
Constructors
| SDUSize | |
Fields
| |
Instances
| Enum SDUSize Source # | |||||
| Generic SDUSize Source # | |||||
Defined in Network.Mux.Types Associated Types
| |||||
| Num SDUSize Source # | |||||
| Integral SDUSize Source # | |||||
Defined in Network.Mux.Types | |||||
| Real SDUSize Source # | |||||
Defined in Network.Mux.Types Methods toRational :: SDUSize -> Rational # | |||||
| Show SDUSize Source # | |||||
| Eq SDUSize Source # | |||||
| Ord SDUSize Source # | |||||
| type Rep SDUSize Source # | |||||
Defined in Network.Mux.Types | |||||
Monitoring
miniProtocolStateMap :: forall (m :: Type -> Type) (mode :: Mode). MonadSTM m => Mux mode m -> Map (MiniProtocolNum, MiniProtocolDir) (STM m MiniProtocolStatus) Source #
Get information about all statically registered mini-protocols.
stopped :: forall (m :: Type -> Type) (mode :: Mode). MonadSTM m => Mux mode m -> STM m (Maybe SomeException) Source #
Await until mux stopped.
Errors
Enumeration of error conditions.
Constructors
| UnknownMiniProtocol MiniProtocolNum | returned by |
| BearerClosed String | thrown by |
| IngressQueueOverRun MiniProtocolNum MiniProtocolDir | thrown by |
| InitiatorOnly MiniProtocolNum | thrown when data arrives on a responder channel when the
mux was set up as an |
| IOException IOException String |
|
| SDUDecodeError String | return by |
| SDUReadTimeout | thrown when reading of a single SDU takes too long |
| SDUWriteTimeout | thrown when writing a single SDU takes too long |
| Shutdown (Maybe SomeException) Status | Result of runMiniProtocol's completionAction in case of an error or mux being closed while a mini-protocol was still running, this is not a clean exit. |
Instances
| Exception Error Source # | |
Defined in Network.Mux.Trace Methods toException :: Error -> SomeException # fromException :: SomeException -> Maybe Error # displayException :: Error -> String # backtraceDesired :: Error -> Bool # | |
| Show Error Source # | |
data RuntimeError Source #
Constructors
| ProtocolAlreadyRunning !MiniProtocolNum !MiniProtocolDir !MiniProtocolStatus | |
| UnknownProtocolInternalError !MiniProtocolNum !MiniProtocolDir | |
| BlockedOnCompletionVar !MiniProtocolNum |
Instances
| Exception RuntimeError Source # | |
Defined in Network.Mux.Types Methods toException :: RuntimeError -> SomeException # fromException :: SomeException -> Maybe RuntimeError # displayException :: RuntimeError -> String # backtraceDesired :: RuntimeError -> Bool # | |
| Show RuntimeError Source # | |
Defined in Network.Mux.Types Methods showsPrec :: Int -> RuntimeError -> ShowS # show :: RuntimeError -> String # showList :: [RuntimeError] -> ShowS # | |
Tracing
data Tracers' (m :: Type -> Type) (f :: Type -> Type) Source #
Bundle of tracers used directly by mux.
Constructors
| Tracers | |
Fields
| |
Bundled Patterns
| pattern TracersI :: Tracer m Trace -> Tracer m ChannelTrace -> Tracer m BearerTrace -> Tracers m | A convenient bidirectional pattern synonym which (un)wraps the |
nullTracers :: forall (m :: Type -> Type) (f :: Type -> Type). Applicative m => Tracers' m f Source #
contramapTracers' :: forall f' f (m :: Type -> Type). (forall x. f' x -> f x) -> Tracers' m f -> Tracers' m f' Source #
Contravariant natural transformation of Tracers m`.
High-level mux events.
Constructors
data BearerTrace Source #
Low-level bearer trace tags (these are not traced by the tracer which is passed to Mux).
Constructors
Instances
| Show BearerTrace Source # | |
Defined in Network.Mux.Types Methods showsPrec :: Int -> BearerTrace -> ShowS # show :: BearerTrace -> String # showList :: [BearerTrace] -> ShowS # | |
data ChannelTrace Source #
Mid-level channel events traced independently by each mini protocol job.
Constructors
| TraceChannelRecvStart MiniProtocolNum | |
| TraceChannelRecvEnd MiniProtocolNum Int | |
| TraceChannelSendStart MiniProtocolNum Int | |
| TraceChannelSendEnd MiniProtocolNum |
Instances
| Show ChannelTrace Source # | |
Defined in Network.Mux.Trace Methods showsPrec :: Int -> ChannelTrace -> ShowS # show :: ChannelTrace -> String # showList :: [ChannelTrace] -> ShowS # | |
data WithBearer peerid a Source #
Type used for tracing mux events.
Constructors
| WithBearer | |
Instances
| Generic (WithBearer peerid a) Source # | |||||
Defined in Network.Mux.Trace Associated Types
Methods from :: WithBearer peerid a -> Rep (WithBearer peerid a) x # to :: Rep (WithBearer peerid a) x -> WithBearer peerid a # | |||||
| (Show peerid, Show a) => Show (WithBearer peerid a) Source # | |||||
Defined in Network.Mux.Trace Methods showsPrec :: Int -> WithBearer peerid a -> ShowS # show :: WithBearer peerid a -> String # showList :: [WithBearer peerid a] -> ShowS # | |||||
| type Rep (WithBearer peerid a) Source # | |||||
Defined in Network.Mux.Trace type Rep (WithBearer peerid a) = D1 ('MetaData "WithBearer" "Network.Mux.Trace" "network-mux-0.9.1.0-inplace" 'False) (C1 ('MetaCons "WithBearer" 'PrefixI 'True) (S1 ('MetaSel ('Just "wbPeerId") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 peerid) :*: S1 ('MetaSel ('Just "wbEvent") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 a))) | |||||
type TracersWithBearer connId (m :: Type -> Type) = Tracers' m (WithBearer connId) Source #
tracersWithBearer :: forall peerId (m :: Type -> Type). peerId -> TracersWithBearer peerId m -> Tracers m Source #