Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- runPeer :: forall ps (st :: ps) (pr :: PeerRole) failure bytes m a. (MonadThrow m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> Peer ps pr 'NonPipelined st m a -> m (a, Maybe bytes)
- runPipelinedPeer :: forall ps (st :: ps) (pr :: PeerRole) failure bytes m a. (MonadAsync m, MonadThrow m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> PeerPipelined ps pr st m a -> m (a, Maybe bytes)
- data TraceSendRecv ps where
- TraceSendMsg :: forall ps. AnyMessage ps -> TraceSendRecv ps
- TraceRecvMsg :: forall ps. AnyMessage ps -> TraceSendRecv ps
- data Role
- data DecoderFailure where
- DecoderFailure :: forall ps (st :: ps) failure. (Show failure, Show (StateToken st), ShowProxy ps, ActiveState st) => StateToken st -> failure -> DecoderFailure
- runConnectedPeers :: forall ps (pr :: PeerRole) (st :: ps) failure bytes m a b. (MonadAsync m, MonadThrow m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => m (Channel m bytes, Channel m bytes) -> Tracer m (Role, TraceSendRecv ps) -> Codec ps failure m bytes -> Peer ps pr 'NonPipelined st m a -> Peer ps (FlipAgency pr) 'NonPipelined st m b -> m (a, b)
- runConnectedPeersPipelined :: forall m ps failure bytes (pr :: PeerRole) (st :: ps) a b. (MonadAsync m, MonadCatch m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => m (Channel m bytes, Channel m bytes) -> Tracer m (Role, TraceSendRecv ps) -> Codec ps failure m bytes -> PeerPipelined ps pr st m a -> Peer ps (FlipAgency pr) 'NonPipelined st m b -> m (a, b)
- runConnectedPeersAsymmetric :: forall m ps failure bytes (pr :: PeerRole) (st :: ps) a b. (MonadAsync m, MonadMask m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => m (Channel m bytes, Channel m bytes) -> Tracer m (Role, TraceSendRecv ps) -> Codec ps failure m bytes -> Codec ps failure m bytes -> Peer ps pr 'NonPipelined st m a -> Peer ps (FlipAgency pr) 'NonPipelined st m b -> m (a, b)
Introduction
A Peer
is a particular implementation of an agent that engages in a
typed protocol. To actualy run one we need a source and sink for the typed
protocol messages. These are provided by a Channel
and a Codec
. The
Channel
represents one end of an untyped duplex message transport, and
the Codec
handles conversion between the typed protocol messages and
the untyped channel.
So given the Peer
and a compatible Codec
and Channel
we can run the
peer in some appropriate monad. The peer and codec have to agree on
the same protocol and role in that protocol. The codec and channel have to
agree on the same untyped medium, e.g. text or bytes. All three have to
agree on the same monad in which they will run.
This module provides drivers for normal and pipelined peers. There is very little policy involved here so typically it should be possible to use these drivers, and customise things by adjusting the peer, or codec or channel.
It is of course possible to write custom drivers and the code for these ones
may provide a useful starting point. The runDecoder
function may be a
helpful utility for use in custom drives.
runPeer :: forall ps (st :: ps) (pr :: PeerRole) failure bytes m a. (MonadThrow m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> Peer ps pr 'NonPipelined st m a -> m (a, Maybe bytes) Source #
Run a peer with the given channel via the given codec.
This runs the peer to completion (if the protocol allows for termination).
runPipelinedPeer :: forall ps (st :: ps) (pr :: PeerRole) failure bytes m a. (MonadAsync m, MonadThrow m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> PeerPipelined ps pr st m a -> m (a, Maybe bytes) Source #
Run a pipelined peer with the given channel via the given codec.
This runs the peer to completion (if the protocol allows for termination).
Unlike normal peers, running pipelined peers rely on concurrency, hence the
MonadAsync
constraint.
data TraceSendRecv ps where Source #
TraceSendMsg :: forall ps. AnyMessage ps -> TraceSendRecv ps | |
TraceRecvMsg :: forall ps. AnyMessage ps -> TraceSendRecv ps |
Instances
Show (AnyMessage ps) => Show (TraceSendRecv ps) Source # | |
Defined in Ouroboros.Network.Driver.Simple showsPrec :: Int -> TraceSendRecv ps -> ShowS # show :: TraceSendRecv ps -> String # showList :: [TraceSendRecv ps] -> ShowS # |
data DecoderFailure where Source #
DecoderFailure :: forall ps (st :: ps) failure. (Show failure, Show (StateToken st), ShowProxy ps, ActiveState st) => StateToken st -> failure -> DecoderFailure |
Instances
Exception DecoderFailure Source # | |
Defined in Ouroboros.Network.Driver.Simple | |
Show DecoderFailure Source # | |
Defined in Ouroboros.Network.Driver.Simple showsPrec :: Int -> DecoderFailure -> ShowS # show :: DecoderFailure -> String # showList :: [DecoderFailure] -> ShowS # |
Connected peers
runConnectedPeers :: forall ps (pr :: PeerRole) (st :: ps) failure bytes m a b. (MonadAsync m, MonadThrow m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => m (Channel m bytes, Channel m bytes) -> Tracer m (Role, TraceSendRecv ps) -> Codec ps failure m bytes -> Peer ps pr 'NonPipelined st m a -> Peer ps (FlipAgency pr) 'NonPipelined st m b -> m (a, b) Source #
Run two Peer
s via a pair of connected Channel
s and a common Codec
.
This is useful for tests and quick experiments.
The first argument is expected to create two channels that are connected,
for example createConnectedChannels
.
runConnectedPeersPipelined :: forall m ps failure bytes (pr :: PeerRole) (st :: ps) a b. (MonadAsync m, MonadCatch m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => m (Channel m bytes, Channel m bytes) -> Tracer m (Role, TraceSendRecv ps) -> Codec ps failure m bytes -> PeerPipelined ps pr st m a -> Peer ps (FlipAgency pr) 'NonPipelined st m b -> m (a, b) Source #
runConnectedPeersAsymmetric :: forall m ps failure bytes (pr :: PeerRole) (st :: ps) a b. (MonadAsync m, MonadMask m, ShowProxy ps, forall (st' :: ps) stok. stok ~ StateToken st' => Show stok, Show failure) => m (Channel m bytes, Channel m bytes) -> Tracer m (Role, TraceSendRecv ps) -> Codec ps failure m bytes -> Codec ps failure m bytes -> Peer ps pr 'NonPipelined st m a -> Peer ps (FlipAgency pr) 'NonPipelined st m b -> m (a, b) Source #
Run the same protocol with different codecs. This is useful for testing
Handshake
protocol which knows how to decode different versions.