network-mux
Safe HaskellNone
LanguageHaskell2010

Network.Mux.Counters

Description

Node-wide mux counters: how the muxes of one set have failed, counted once per mux as it dies, and the bytes they sent and read, by mini-protocol and direction; a remote set and a local one, traced periodically.

Synopsis

Counters

data Counters (m :: Type -> Type) Source #

Counters shared by every mux of one set: the failures, and the byte cells of the live muxes beside the totals of the ones that have ended, so a total never goes down when a connection closes.

withCounters Source #

Arguments

:: (MonadAsync m, MonadDelay m) 
=> DiffTime 
-> Bool

a local set too

-> Tracer m CountersTrace 
-> (Maybe (Counters m) -> Maybe (Counters m) -> m a) 
-> m a 

Counter sets for as long as k runs: one for the remote muxes and, if asked, one for the local muxes, each traced every interval, a second at least, by countersLoop raced with k, so an exception in either ends both. An interval of zero, or less, makes no set: the muxes count nothing and nothing is traced. The only way to a set from Network.Mux, so none is kept without the loop that reads it; the internals below make one for the mux's tests.

readCounters :: forall (m :: Type -> Type). MonadSTM m => Counters m -> STM m Counts Source #

The failures with the bytes of every mux, ended or live, summed in, in one transaction: for tests and small sets, as a transaction over every live mux's counters is restarted by any muxer or demuxer writing one it has read, and reads them all over again; a node reads with the loop's snapshot, a transaction per counter.

data Counts Source #

One side's counters at an instant.

Constructors

Counts 

Fields

Instances

Instances details
Show Counts Source # 
Instance details

Defined in Network.Mux.Counters

Eq Counts Source # 
Instance details

Defined in Network.Mux.Counters

Methods

(==) :: Counts -> Counts -> Bool #

(/=) :: Counts -> Counts -> Bool #

data Failures Source #

How the muxes have failed, each failure counted once, as the mux died of it.

Constructors

Failures 

Fields

  • mfWriteTimeouts :: !Word64

    the peer took nothing within the SDU timeout

  • mfWriteErrors :: !Word64

    the bearer's write failed otherwise: a timed-out connection, a host unreachable

  • mfReadTimeouts :: !Word64

    an SDU header arrived, the rest did not in time

  • mfOverruns :: !Word64

    the peer exceeded a mini-protocol's ingress limit

  • mfProtocolErrors :: !Word64

    undecodable SDUs, unknown mini-protocols, data an initiator-only mux cannot take

  • mfReadErrors :: !Word64

    the bearer's read failed otherwise: a connection that timed out, a host unreachable

  • mfPeerClosed :: !Word64

    the peer closed the connection and the mux failed of it: read as its end while a mini-protocol was running, or met as a reset or a broken pipe by a read or a write

  • mfOtherErrors :: !Word64

    the muxer or the demuxer died with an exception of a kind not listed, asynchronous ones aside: an encoding that would not force, a bug

  • mfMiniProtocols :: !(Map (MiniProtocolNum, MiniProtocolDir) Word64)

    a mini-protocol's thread died with an exception of its own, by protocol and our side's direction: a violation it detected, its time limit

Instances

Instances details
Show Failures Source # 
Instance details

Defined in Network.Mux.Counters

Eq Failures Source # 
Instance details

Defined in Network.Mux.Counters

noFailures :: Failures Source #

No failure counted.

noCounts :: Counts Source #

Nothing counted.

type ByteCounts = Map (MiniProtocolNum, MiniProtocolDir) Word64 Source #

Bytes on the wire, SDU headers included, by mini-protocol number and the direction of our side of it: what our initiators and our responders sent, or what was read for them. The handshake's bytes, run on the bearer before the mux, are not among them.

Tracing

data CountersTrace Source #

A snapshot of one set's counters.

Constructors

TraceRemoteCounters Counts

the remote muxes

TraceLocalCounters Counts

the local muxes

Instances

Instances details
Show CountersTrace Source # 
Instance details

Defined in Network.Mux.Counters

Eq CountersTrace Source # 
Instance details

Defined in Network.Mux.Counters

countersInterval :: DiffTime Source #

A prime, so that snapshots do not keep step with other periodic work such as keep-alive, and shorter than a 10 s scrape interval.

Internal, for the mux and the tests

newCounters :: MonadSTM m => m (Counters m) Source #

A fresh set, nothing counted.

countersLoop Source #

Arguments

:: (MonadDelay m, MonadSTM m) 
=> Maybe (Counters m)

the remote set, if any

-> Maybe (Counters m)

the local set, if any

-> DiffTime 
-> Tracer m CountersTrace 
-> m void 

Every interval, a second at least, snapshot the remote and the local set, each if there is one, and trace each. withCounters runs it for the sets it makes.

type ByteSlots (m :: Type -> Type) = Map (MiniProtocolNum, MiniProtocolDir) (StrictTVar m Word64) Source #

One mux's byte counters, one per mini-protocol and direction it runs, written only by its own muxer or demuxer, so no two connections share a variable on the data path; made by newByteSlots.

withByteCells :: (MonadSTM m, MonadMask m) => Maybe (Counters m) -> Map (MiniProtocolNum, MiniProtocolDir) (IngressQueue m) -> (ByteSlots m -> m a) -> m a Source #

Byte cells for a mux for the duration of k, which is given the muxer's slots: one per mini-protocol and direction, beside the ingress queues given, which count what the demuxer reads whether or not anyone looks. With counters the slots are made and the cells registered as the mux starts, and on the way out their counts move into the retired totals in the same transaction that unregisters them; without, there are no slots, so the muxer counts nothing.

newByteSlots :: forall (m :: Type -> Type). MonadSTM m => [(MiniProtocolNum, MiniProtocolDir)] -> STM m (ByteSlots m) Source #

A slot per mini-protocol and direction given, at zero. A mux makes its muxer's for every mini-protocol it runs; an SDU for a key not among them is not counted.

readSlots :: forall (m :: Type -> Type). MonadSTM m => ByteSlots m -> STM m ByteCounts Source #

The counts in the slots, leaving out the ones still at zero: a protocol appears once it has carried something.

countMuxerFailure :: forall (m :: Type -> Type). MonadSTM m => Maybe (Counters m) -> SomeException -> STM m () Source #

Count the exception a mux's muxer died with.

countDemuxerFailure :: forall (m :: Type -> Type). MonadSTM m => Maybe (Counters m) -> SomeException -> STM m () Source #

Count the exception a mux's demuxer died with, the mux failing of it.

countMiniProtocolFailure :: forall (m :: Type -> Type). MonadSTM m => Maybe (Counters m) -> MiniProtocolNum -> MiniProtocolDir -> SomeException -> STM m () Source #

Count the exception a mini-protocol's thread died with, by its protocol and our side's direction, unless it is the mux's own or asynchronous, which is the mux ending.

snapshotCountersWith :: forall (m :: Type -> Type) n. (MonadSTM m, Monad n) => (forall a. STM m a -> n a) -> Counters m -> n Counts Source #

The same, with each read run by runTx: in a transaction for the totals and one per counter of each live mux, so no transaction spans more than one variable a muxer or a demuxer writes, and a busy connection makes it rerun at most the read of one. The totals and the live set go together, before the cells: a mux that ends in between is in the live set and not yet in the totals, and its cells, which ending leaves as they were, count it once; a sum never goes down across snapshots.