Safe Haskell | None |
---|---|
Language | Haskell2010 |
Ouroboros.Network.PeerSelection.PeerStateActions
Contents
Synopsis
- data PeerStateActionsArguments muxMode socket peerAddr versionNumber m a b = PeerStateActionsArguments {
- spsTracer ∷ Tracer m (PeerSelectionActionsTrace peerAddr)
- spsDeactivateTimeout ∷ DiffTime
- spsCloseConnectionTimeout ∷ DiffTime
- spsConnectionManager ∷ MuxConnectionManager muxMode socket peerAddr versionNumber ByteString m a b
- data PeerConnectionHandle (muxMode ∷ MuxMode) peerAddr bytes m a b
- withPeerStateActions ∷ ∀ (muxMode ∷ MuxMode) socket peerAddr versionNumber m a b x. (MonadAsync m, MonadCatch m, MonadLabelledSTM m, MonadMask m, MonadTimer m, MonadThrow (STM m), HasInitiator muxMode ~ True, Typeable versionNumber, Show versionNumber, Ord peerAddr, Typeable peerAddr, Show peerAddr) ⇒ PeerStateActionsArguments muxMode socket peerAddr versionNumber m a b → (PeerStateActions peerAddr (PeerConnectionHandle muxMode peerAddr ByteString m a b) m → m x) → m x
- data PeerSelectionActionException = ∀ e.Exception e ⇒ PeerSelectionActionException e
- data EstablishConnectionException versionNumber
- = ClientException !(HandshakeException versionNumber)
- | ServerException !(HandshakeException versionNumber)
- data PeerSelectionTimeoutException peerAddr
- = DeactivationTimeout !(ConnectionId peerAddr)
- | CloseConnectionTimeout !(ConnectionId peerAddr)
- data PeerSelectionActionsTrace peerAddr
- = PeerStatusChanged (PeerStatusChangeType peerAddr)
- | PeerStatusChangeFailure (PeerStatusChangeType peerAddr) FailureType
- | PeerMonitoringError (ConnectionId peerAddr) SomeException
- | PeerMonitoringResult (ConnectionId peerAddr) (WithSomeProtocolTemperature FirstToFinishResult)
Documentation
Introduction
This module implements PeerStateActions
, which provide the following
capabilities::
- synchronous promotions / demotions
- asynchronous demotions
Monitor mini-protocols and act on mini-protocol state changes done via
monitorPeerConnection
.
Synchronous promotions / demotions
Synchronous promotions / demotions are directly used by
peerSelectionGovernor
.
- synchronous cold → warm transition
- This transition starts with creating or reusing an inbound connection, do handshake (functionality provided by connection manager), start established and warm mini-protocols, start monitoring thread specified below.
- synchronous warm → hot transition
- This transition quiesce warm protocols and starts hot protocols. There is no timeout to quiesce warm mini-protocols. The tip-sample protocol which is the only planned warm protocol has some states that have a longer timeout when the remote peer has agency, but it does not transfers much data.
- synchronous hot → warm transition
- Within a timeout, stop hot protocols and let the warm protocols continue running. If the timeout expires the connection is closed. Note that this will impact inbound side of a duplex connection. We cannot do any better: closing is a cooperative action since we require to arrive at a well defined state of the multiplexer (no outstanding data in ingress queue). This transition must use last to finish synchronisation of all hot mini-protocols.
- synchronous warm → cold transition
- Shutdown established and warm protocols. As in the previous transition it must use last to finish synchronisation on established and warm protocol termination, if this synchronisation timeouts the connection is closed.
Monitoring Loop
The monitoring loop is responsible for taking an action when one of the mini-protocols either terminates or errors. Except termination of a hot protocols we shall close the connection. When one of the hot protocols terminates we trigger a synchronous hot → warm transition.
The monitoring loop is supposed to stop when the multiplexer stops.
Note that the monitoring loop must act as soon as one of the mini-protocols terminates or errors, hence the use of first to finish synchronisation.
The multiplexer guarantees that whenever one of the mini-protocols errors the connection is closed. This simplifies the actions needed to be taken by the monitoring loop.
Asynchronous demotions
- asynchronous * → cold transition
- This demotion is triggered whenever any of the mini-protocol errors. This does not require a further action by the monitoring loop: mux will close the connection, monitoring loop will terminate.
- asynchronous hot → warm demotion
- This demotion is triggered if a hot mini-protocol terminates cleanly. In this case we trigger synchronous hot → warm demotion which will halt all hot mini-protocols and will notify the peer-to-peer governor about the change.
Implementation details
PeerStateActions
are build on top of ConnectionManager
which provides
a primitive to present us a negotiated connection (i.e. after running
the handshake) and the multiplexer api which allows to start mini-protocols
and track their termination via an STM
interface. Each connection has
associated PeerConnectionHandle
which holds all the data associated with
a connection.
Most important are pchMux :: Mux mode m
which allows us
to interact with the multiplexer and pchAppHandles
. The latter contains
information about each mini-protocol and its STM
mini-protocol monitoring
action. ahMiniProtocolResults
allows us to build last-to-finish
awaitAllResults
and first-to-finish awaitFirstResult
synchronisations that
we need in synchronous transitions and monitoring loop respectively.
ahControlVar
is a per-temperature TVar
which holds ControlMessage
. It
is passed from ConnectionHandler
via Handle
. This variable allows
us to terminate, quiesce or re-enable mini-protocols.
Bellow is a schematic illustration of function calls / threads and shared
state variables. Reads done just make assertions are not included. The
diagram does not include establishPeerConnection
.
Legend: ─ - functions │░ - threads ━ - STM mutable variables ├──▶┃ - write to a TVar │◀──┨ - read from a TVar ├──▶│ - function call PeerStateVar - 'pchPeerState' 'TVar' MiniProtocolResults - 'ahMiniProtocolResults' 'TVar' ControlVar - 'ahControlVar' 'TVar' ┌──────────────────────────────────────────┐ │ ┌────────┐ │ │ │ │ │ ┌────────────────┴─┴─┐ │ │ ┌────────────────────┐│ ▼ ▼ ┌────────────────────┐││ ┌──────────────────────────┐ ┌─────────────────────┐ │░░░░░░░░░░░░░░░░░░░░│││ │ │ │ │ │░peerMonitoringLoop░││┘ │ deactivatePeerConnection │ │ closePeerConnection │ │░░░░░░░░░░░░░░░░░░░░│┘ │ │ │ │ └┬───────────────────┘ └┬────────────────────┬────┘ └───────┬─────────────┘ │ ▲ │ ▲ │ ▲ ▲ │ │ ┌───┼────────────────────┘ │ │ │ │ │ │ │ ┌─┼────────────────────────┼────────────────┼──────────────┘ │ │ │ │ │ │ │ ┌──────────┼────────────────┘ │ │ │ │ │ │ │ │ ┌────────────────┘ ▒▒│▒│▒│▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│▒▒▒▒▒│▒▒▒▒▒▒▒▒▒▒│▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒ │ │ │ └───────────────┐ │ │ │ │ ▒▒▒ ▒ ▼ ▼ ▼ │ │ │ ▼ ▼ ▒ ▒▒▒ ▒┏━━━━━━━━━━━━━━┓ ┏┷━━━━━━━━┷━━━━━┷┓ ┏━━━━━━━━━━━━━━━━┓ ▒ ▒ ▒ ▒┃ ┃┓ ┃ ┃┓ ┃ ┃┓ ▒ ▒ ▒ ▒┃ PeerStateVar ┃┃┓ ┃ MiniProtocol ┃┃┓ ┃ ControlVar ┃┃┓ ▒ ▒ ▒ ▒┃ ┃┃┃ ┃ Results ┃┃┃ ┃ - established ┃┃┃ ▒ ▒ ▒ ▒┃ ┃┃┃ ┃ - established ┃┃┃ ┃ - warm ┃┃┃ ▒ ▒ ▒ ▒┗━━━━━━━━━━━━━━┛┃┃ ┃ - warm ┃┃┃ ┃ - hot ┃┃┃ ▒ ▒ ▒ ▒ ┗━━━━━━━━━━━━━━┛┃ ┃ - hot ┃┃┃ ┃ ┃┃┃ ▒ ▒ ▒ ▒ ┗━━━━━━━━━━━━━━┛ ┃ ┃┃┃ ┃ ┃┃┃ ▒ ▒ ▒ ▒ ▲ ┗━━━━━━━━━━━━━━━━┛┃┃ ┗━━━━━━━━━━━━━━━━┛┃┃ ▒ ▒ ▒ ▒ │ ┗━━━━━━━━━━━━━━━━┛┃ ┗━━━━━━━━━━━━━━━━┛┃ ▒ ▒ ▒ ▒ │ ┗━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━┛ ▒ ▒ ▒ ▒ │ ▲ ▒ ▒ ▒ ▒ │ PeerConnectionHandles │ ▒ ▒ ▒ ▒▒▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒ ▒ ▒ │ │ ▒ ▒ ▒▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒ ▒│ │ ▒ ▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │ ┌─────────────────────────┘ ┌─┴───────────────────┴──┐ │ │ │ activatePeerConnection │ │ │ └────────────────────────┘
Notes:
All three upper boxes: peerMonitoringLoop
, deactivatePeerConnection
and
closePeerConnection
are reading ahMiniProtocolResults
via the
last-to-finish awaitAllResults
synchronisation.
All of the thin boxes are writing to pchPeerState
variable; which is read
by 'monitorPeerConnection. Also all of them writing to ahControlVar
:
peerMonitoringLoop
does that through a call to deactivePeerConnection
or
closePeerConnection
.
data PeerStateActionsArguments muxMode socket peerAddr versionNumber m a b Source #
Record of arguments of peerSelectionActions
.
Constructors
PeerStateActionsArguments | |
Fields
|
data PeerConnectionHandle (muxMode ∷ MuxMode) peerAddr bytes m a b Source #
Each established connection has access to PeerConnectionHandle
. It
allows to promote / demote or close the connection, by having access to
Mux
, three bundles of miniprotocols: for hot, warm and established peers
together with their state StrictTVar
s.
Instances
Show peerAddr ⇒ Show (PeerConnectionHandle muxMode peerAddr bytes m a b) Source # | |
withPeerStateActions ∷ ∀ (muxMode ∷ MuxMode) socket peerAddr versionNumber m a b x. (MonadAsync m, MonadCatch m, MonadLabelledSTM m, MonadMask m, MonadTimer m, MonadThrow (STM m), HasInitiator muxMode ~ True, Typeable versionNumber, Show versionNumber, Ord peerAddr, Typeable peerAddr, Show peerAddr) ⇒ PeerStateActionsArguments muxMode socket peerAddr versionNumber m a b → (PeerStateActions peerAddr (PeerConnectionHandle muxMode peerAddr ByteString m a b) m → m x) → m x Source #
Exceptions
data PeerSelectionActionException Source #
Parent exception of all peer selection action exceptions.
Constructors
∀ e.Exception e ⇒ PeerSelectionActionException e |
data EstablishConnectionException versionNumber Source #
Constructors
ClientException !(HandshakeException versionNumber) | Handshake client failed |
ServerException !(HandshakeException versionNumber) | Handshake server failed |
Instances
Show versionNumber ⇒ Show (EstablishConnectionException versionNumber) Source # | |
(Show versionNumber, Typeable versionNumber) ⇒ Exception (EstablishConnectionException versionNumber) Source # | |
Defined in Ouroboros.Network.PeerSelection.PeerStateActions Methods toException ∷ EstablishConnectionException versionNumber → SomeException Source # fromException ∷ SomeException → Maybe (EstablishConnectionException versionNumber) Source # displayException ∷ EstablishConnectionException versionNumber → String Source # |
data PeerSelectionTimeoutException peerAddr Source #
Constructors
DeactivationTimeout !(ConnectionId peerAddr) | |
CloseConnectionTimeout !(ConnectionId peerAddr) |
Instances
Show peerAddr ⇒ Show (PeerSelectionTimeoutException peerAddr) Source # | |
(Show peerAddr, Typeable peerAddr) ⇒ Exception (PeerSelectionTimeoutException peerAddr) Source # | |
Defined in Ouroboros.Network.PeerSelection.PeerStateActions Methods toException ∷ PeerSelectionTimeoutException peerAddr → SomeException Source # fromException ∷ SomeException → Maybe (PeerSelectionTimeoutException peerAddr) Source # displayException ∷ PeerSelectionTimeoutException peerAddr → String Source # |
Trace
data PeerSelectionActionsTrace peerAddr Source #
Traces produced by peerSelectionActions
.
Constructors
PeerStatusChanged (PeerStatusChangeType peerAddr) | |
PeerStatusChangeFailure (PeerStatusChangeType peerAddr) FailureType | |
PeerMonitoringError (ConnectionId peerAddr) SomeException | |
PeerMonitoringResult (ConnectionId peerAddr) (WithSomeProtocolTemperature FirstToFinishResult) |
Instances
Show peerAddr ⇒ Show (PeerSelectionActionsTrace peerAddr) Source # | |