{-# LANGUAGE DataKinds             #-}
{-# LANGUAGE DeriveFoldable        #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE KindSignatures        #-}
{-# LANGUAGE NamedFieldPuns        #-}
{-# LANGUAGE RankNTypes            #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TupleSections         #-}
-- Undecidable instances are need for 'Show' instance of 'ConnectionState'.
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE UndecidableInstances  #-}

-- | The implementation of connection manager.
--
module Ouroboros.Network.ConnectionManager.Core
  ( ConnectionManagerArguments (..)
  , withConnectionManager
  , defaultTimeWaitTimeout
  , defaultProtocolIdleTimeout
  , defaultResetTimeout
  , ConnectionState (..)
  , abstractState
  ) where

import           Control.Exception (assert)
import           Control.Monad (forM_, guard, when, (>=>))
import           Control.Monad.Class.MonadAsync
import           Control.Monad.Class.MonadFork (MonadFork, ThreadId, throwTo)
import qualified Control.Monad.Class.MonadSTM as LazySTM
import           Control.Monad.Class.MonadSTM.Strict
import           Control.Monad.Class.MonadThrow hiding (handle)
import           Control.Monad.Class.MonadTime
import           Control.Monad.Class.MonadTimer
import           Control.Monad.Fix
import           Control.Tracer (Tracer, contramap, traceWith)
import           Data.Foldable (foldMap', traverse_)
import           Data.Function (on)
import           Data.Functor (void, ($>))
import           Data.Maybe (maybeToList)
import           Data.Proxy (Proxy (..))
import           Data.Typeable (Typeable)
import           GHC.Stack (CallStack, HasCallStack, callStack)

import           Data.Map (Map)
import qualified Data.Map as Map
import qualified Data.Set as Set

import           Data.Monoid.Synchronisation
import           Data.Wedge
import           Data.Word (Word32)

import           Network.Mux.Trace (MuxTrace, WithMuxBearer (..))
import           Network.Mux.Types (MuxMode)

import           Ouroboros.Network.ConnectionId
import           Ouroboros.Network.ConnectionManager.Types
import qualified Ouroboros.Network.ConnectionManager.Types as CM
import           Ouroboros.Network.InboundGovernor.ControlChannel
                     (ControlChannel)
import qualified Ouroboros.Network.InboundGovernor.ControlChannel as ControlChannel
import           Ouroboros.Network.MuxMode
import           Ouroboros.Network.Server.RateLimiting
                     (AcceptedConnectionsLimit (..))
import           Ouroboros.Network.Snocket


-- | Arguments for a 'ConnectionManager' which are independent of 'MuxMode'.
--
data ConnectionManagerArguments handlerTrace socket peerAddr handle handleError version m =
    ConnectionManagerArguments {
        -- | Connection manager tracer.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
cmTracer              :: Tracer m (ConnectionManagerTrace peerAddr handlerTrace),

        -- | Trace state transitions.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Tracer
     m
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
cmTrTracer            :: Tracer m (TransitionTrace peerAddr (ConnectionState peerAddr handle handleError version m)),

        -- | Mux trace.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Tracer m (WithMuxBearer (ConnectionId peerAddr) MuxTrace)
cmMuxTracer           :: Tracer m (WithMuxBearer (ConnectionId peerAddr) MuxTrace),

        -- | @IPv4@ address of the connection manager.  If given, outbound
        -- connections to an @IPv4@ address will bound to it.  To use
        -- bidirectional @TCP@ connections, it must be the same as the server
        -- listening @IPv4@ address.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Maybe peerAddr
cmIPv4Address         :: Maybe peerAddr,

        -- | @IPv6@ address of the connection manager.  If given, outbound
        -- connections to an @IPv6@ address will bound to it.  To use
        -- bidirectional @TCP@ connections, it must be the same as the server
        -- listening @IPv6@ address.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Maybe peerAddr
cmIPv6Address         :: Maybe peerAddr,

        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> peerAddr -> Maybe AddressType
cmAddressType         :: peerAddr -> Maybe AddressType,

        -- | Snocket for the 'socket' type.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Snocket m socket peerAddr
cmSnocket             :: Snocket m socket peerAddr,

        -- | @TCP@ will held connections in @TIME_WAIT@ state for up to two MSL
        -- (maximum segment time).  On Linux this is set to '60' seconds on
        -- other system this might be up to four minutes.
        --
        -- This is configurable, so we can set different value in tests.
        --
        -- When this timeout expires a connection will transition from
        -- 'TerminatingState' to 'TerminatedState'.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> DiffTime
cmTimeWaitTimeout     :: DiffTime,

        -- | Inactivity timeout before the connection will be reset.  It is the
        -- timeout attached to the 'OutboundIdleState'.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> DiffTime
cmOutboundIdleTimeout :: DiffTime,

        -- | @version@ represents the tuple of @versionNumber@ and
        -- @agreedOptions@.
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> version -> DataFlow
connectionDataFlow    :: version -> DataFlow,

        -- | Prune policy
        --
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> PrunePolicy peerAddr (STM m)
cmPrunePolicy         :: PrunePolicy peerAddr (STM m),
        ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> AcceptedConnectionsLimit
cmConnectionsLimits   :: AcceptedConnectionsLimit
      }


-- | 'MutableConnState', which supplies a unique identifier.
--
-- TODO: We can get away without id, by tracking connections in
-- `TerminatingState` using a seprate priority search queue.
--
data MutableConnState peerAddr handle handleError version m = MutableConnState {
    -- | A unique identifier
    --
    MutableConnState peerAddr handle handleError version m -> Int
connStateId  :: !Int

  , -- | Mutable state
    --
    MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar      :: !(StrictTVar m (ConnectionState peerAddr handle handleError
                                                    version m))
  }


instance Eq (MutableConnState peerAddr handle handleError version m) where
    == :: MutableConnState peerAddr handle handleError version m
-> MutableConnState peerAddr handle handleError version m -> Bool
(==) =  Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Int -> Int -> Bool)
-> (MutableConnState peerAddr handle handleError version m -> Int)
-> MutableConnState peerAddr handle handleError version m
-> MutableConnState peerAddr handle handleError version m
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` MutableConnState peerAddr handle handleError version m -> Int
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m -> Int
connStateId


-- | A supply of fresh id's.
--
-- We use a fresh ids for 'MutableConnState'.
--
newtype FreshIdSupply m = FreshIdSupply { FreshIdSupply m -> STM m Int
getFreshId :: STM m Int }


-- | Create a 'FreshIdSupply' inside and 'STM' monad.
--
newFreshIdSupply :: forall m. MonadSTM m
                 => Proxy m -> STM m (FreshIdSupply m)
newFreshIdSupply :: Proxy m -> STM m (FreshIdSupply m)
newFreshIdSupply Proxy m
_ = do
    (StrictTVar m Int
v :: StrictTVar m Int) <- Int -> STM m (StrictTVar m Int)
forall (m :: * -> *) a. MonadSTM m => a -> STM m (StrictTVar m a)
newTVar Int
0
    let getFreshId :: STM m Int
        getFreshId :: STM m Int
getFreshId = do
          Int
c <- StrictTVar m Int -> STM m Int
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar m Int
v
          StrictTVar m Int -> Int -> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar m Int
v (Int -> Int
forall a. Enum a => a -> a
succ Int
c)
          Int -> STM m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
c
    FreshIdSupply m -> STM m (FreshIdSupply m)
forall (m :: * -> *) a. Monad m => a -> m a
return (FreshIdSupply m -> STM m (FreshIdSupply m))
-> FreshIdSupply m -> STM m (FreshIdSupply m)
forall a b. (a -> b) -> a -> b
$ FreshIdSupply :: forall (m :: * -> *). STM m Int -> FreshIdSupply m
FreshIdSupply { STM m Int
getFreshId :: STM m Int
getFreshId :: STM m Int
getFreshId }


newMutableConnState :: MonadSTM m
                    => FreshIdSupply m
                    -> ConnectionState peerAddr handle handleError
                                       version m
                    -> STM m (MutableConnState peerAddr handle handleError
                                               version m)
newMutableConnState :: FreshIdSupply m
-> ConnectionState peerAddr handle handleError version m
-> STM m (MutableConnState peerAddr handle handleError version m)
newMutableConnState FreshIdSupply m
freshIdSupply ConnectionState peerAddr handle handleError version m
connState = do
      Int
connStateId <- FreshIdSupply m -> STM m Int
forall (m :: * -> *). FreshIdSupply m -> STM m Int
getFreshId FreshIdSupply m
freshIdSupply
      StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar <- ConnectionState peerAddr handle handleError version m
-> STM
     m
     (StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a. MonadSTM m => a -> STM m (StrictTVar m a)
newTVar ConnectionState peerAddr handle handleError version m
connState
      MutableConnState peerAddr handle handleError version m
-> STM m (MutableConnState peerAddr handle handleError version m)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableConnState peerAddr handle handleError version m
 -> STM m (MutableConnState peerAddr handle handleError version m))
-> MutableConnState peerAddr handle handleError version m
-> STM m (MutableConnState peerAddr handle handleError version m)
forall a b. (a -> b) -> a -> b
$ MutableConnState :: forall peerAddr handle handleError version (m :: * -> *).
Int
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> MutableConnState peerAddr handle handleError version m
MutableConnState { Int
connStateId :: Int
connStateId :: Int
connStateId, StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar }


-- | 'ConnectionManager' state: for each peer we keep a 'ConnectionState' in
-- a mutable variable, which reduce congestion on the 'TMVar' which keeps
-- 'ConnectionManagerState'.
--
-- It is important we can lookup by remote @peerAddr@; this way we can find if
-- the connection manager is already managing a connection towards that
-- @peerAddr@ and reuse the 'ConnectionState'.
--
type ConnectionManagerState peerAddr handle handleError version m
  = Map peerAddr (MutableConnState peerAddr handle handleError version m)

connectionManagerStateToCounters
  :: Map peerAddr (ConnectionState peerAddr handle handleError version m)
  -> ConnectionManagerCounters
connectionManagerStateToCounters :: Map
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> ConnectionManagerCounters
connectionManagerStateToCounters =
    (ConnectionState peerAddr handle handleError version m
 -> ConnectionManagerCounters)
-> Map
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> ConnectionManagerCounters
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap' ConnectionState peerAddr handle handleError version m
-> ConnectionManagerCounters
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
-> ConnectionManagerCounters
connectionStateToCounters

-- | State of a connection.
--
data ConnectionState peerAddr handle handleError version m =
    -- | Each outbound connections starts in this state.
    ReservedOutboundState

    -- | Each inbound connection starts in this state, outbound connection
    -- reach this state once `connect` call returns.
    --
    -- note: the async handle is lazy, because it's passed with 'mfix'.
  | UnnegotiatedState   !Provenance
                        !(ConnectionId peerAddr)
                         (Async m ())

    -- | @OutboundState Unidirectional@ state.
  | OutboundUniState    !(ConnectionId peerAddr) !(Async m ()) !handle

    -- | Either @OutboundState Duplex@ or @OutobundState^\tau Duplex@.
  | OutboundDupState    !(ConnectionId peerAddr) !(Async m ()) !handle !TimeoutExpired

    -- | Before connection is reset it is put in 'OutboundIdleState' for the
    -- duration of 'cmOutboundIdleTimeout'.
    --
  | OutboundIdleState   !(ConnectionId peerAddr) !(Async m ()) !handle !DataFlow
  | InboundIdleState    !(ConnectionId peerAddr) !(Async m ()) !handle !DataFlow
  | InboundState        !(ConnectionId peerAddr) !(Async m ()) !handle !DataFlow
  | DuplexState         !(ConnectionId peerAddr) !(Async m ()) !handle
  | TerminatingState    !(ConnectionId peerAddr) !(Async m ()) !(Maybe handleError)
  | TerminatedState                              !(Maybe handleError)


-- | Return 'True' for states in which the connection was already closed.
--
connectionTerminated :: ConnectionState peerAddr handle handleError version m
                     -> Bool
connectionTerminated :: ConnectionState peerAddr handle handleError version m -> Bool
connectionTerminated TerminatingState {} = Bool
True
connectionTerminated TerminatedState  {} = Bool
True
connectionTerminated ConnectionState peerAddr handle handleError version m
_                   = Bool
False



-- | Perform counting from an 'AbstractState'
connectionStateToCounters
    :: ConnectionState peerAddr handle handleError version m
    -> ConnectionManagerCounters
connectionStateToCounters :: ConnectionState peerAddr handle handleError version m
-> ConnectionManagerCounters
connectionStateToCounters ConnectionState peerAddr handle handleError version m
state =
    case ConnectionState peerAddr handle handleError version m
state of
      ConnectionState peerAddr handle handleError version m
ReservedOutboundState                 -> ConnectionManagerCounters
forall a. Monoid a => a
mempty

      UnnegotiatedState Provenance
Inbound ConnectionId peerAddr
_ Async m ()
_         -> ConnectionManagerCounters
inboundConn

      UnnegotiatedState Provenance
Outbound ConnectionId peerAddr
_ Async m ()
_        -> ConnectionManagerCounters
outboundConn

      OutboundUniState ConnectionId peerAddr
_ Async m ()
_ handle
_                -> ConnectionManagerCounters
unidirectionalConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
outboundConn

      OutboundDupState  ConnectionId peerAddr
_ Async m ()
_ handle
_ TimeoutExpired
_             -> ConnectionManagerCounters
duplexConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
outboundConn

      OutboundIdleState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
Unidirectional -> ConnectionManagerCounters
unidirectionalConn
                                             ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
outboundConn

      OutboundIdleState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
Duplex         -> ConnectionManagerCounters
duplexConn
                                             ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
outboundConn

      InboundIdleState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
Unidirectional -> ConnectionManagerCounters
unidirectionalConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
inboundConn

      InboundIdleState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
Duplex         -> ConnectionManagerCounters
duplexConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
inboundConn

      InboundState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
Unidirectional     -> ConnectionManagerCounters
unidirectionalConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
inboundConn

      InboundState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
Duplex             -> ConnectionManagerCounters
duplexConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
inboundConn

      DuplexState ConnectionId peerAddr
_ Async m ()
_ handle
_                     -> ConnectionManagerCounters
fullDuplexConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
duplexConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
inboundConn
                                            ConnectionManagerCounters
-> ConnectionManagerCounters -> ConnectionManagerCounters
forall a. Semigroup a => a -> a -> a
<> ConnectionManagerCounters
outboundConn

      TerminatingState ConnectionId peerAddr
_ Async m ()
_ Maybe handleError
_                -> ConnectionManagerCounters
forall a. Monoid a => a
mempty
      TerminatedState Maybe handleError
_                     -> ConnectionManagerCounters
forall a. Monoid a => a
mempty
  where
    fullDuplexConn :: ConnectionManagerCounters
fullDuplexConn     = Int -> Int -> Int -> Int -> Int -> ConnectionManagerCounters
ConnectionManagerCounters Int
1 Int
0 Int
0 Int
0 Int
0
    duplexConn :: ConnectionManagerCounters
duplexConn         = Int -> Int -> Int -> Int -> Int -> ConnectionManagerCounters
ConnectionManagerCounters Int
0 Int
1 Int
0 Int
0 Int
0
    unidirectionalConn :: ConnectionManagerCounters
unidirectionalConn = Int -> Int -> Int -> Int -> Int -> ConnectionManagerCounters
ConnectionManagerCounters Int
0 Int
0 Int
1 Int
0 Int
0
    inboundConn :: ConnectionManagerCounters
inboundConn        = Int -> Int -> Int -> Int -> Int -> ConnectionManagerCounters
ConnectionManagerCounters Int
0 Int
0 Int
0 Int
1 Int
0
    outboundConn :: ConnectionManagerCounters
outboundConn       = Int -> Int -> Int -> Int -> Int -> ConnectionManagerCounters
ConnectionManagerCounters Int
0 Int
0 Int
0 Int
0 Int
1


instance ( Show peerAddr
         , Show handleError
         , Show (ThreadId m)
         , MonadAsync m
         )
      => Show (ConnectionState peerAddr handle handleError version m) where
    show :: ConnectionState peerAddr handle handleError version m -> String
show ConnectionState peerAddr handle handleError version m
ReservedOutboundState = String
"ReservedOutboundState"
    show (UnnegotiatedState Provenance
pr ConnectionId peerAddr
connId Async m ()
connThread) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String
"UnnegotiatedState "
             , Provenance -> String
forall a. Show a => a -> String
show Provenance
pr
             , String
" "
             , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
             , String
" "
             , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
             ]
    show (OutboundUniState ConnectionId peerAddr
connId Async m ()
connThread handle
_handle) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"OutboundState Unidirectional "
             , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
             , String
" "
             , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
             ]
    show (OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
_handle TimeoutExpired
expired) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"OutboundState "
             , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
             , String
" "
             , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
             , String
" "
             , TimeoutExpired -> String
forall a. Show a => a -> String
show TimeoutExpired
expired
             ]
    show (OutboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
_handle DataFlow
df) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"OutboundIdleState "
             , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
             , String
" "
             , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
             , String
" "
             , DataFlow -> String
forall a. Show a => a -> String
show DataFlow
df
             ]
    show (InboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
_handle DataFlow
df) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([ String
"InboundIdleState "
              , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
              , String
" "
              , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
              , String
" "
              , DataFlow -> String
forall a. Show a => a -> String
show DataFlow
df
              ])
    show (InboundState  ConnectionId peerAddr
connId Async m ()
connThread handle
_handle DataFlow
df) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"InboundState "
             , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
             , String
" "
             , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
             , String
" "
             , DataFlow -> String
forall a. Show a => a -> String
show DataFlow
df
             ]
    show (DuplexState   ConnectionId peerAddr
connId Async m ()
connThread handle
_handle) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"DuplexState "
             , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
             , String
" "
             , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
             ]
    show (TerminatingState ConnectionId peerAddr
connId Async m ()
connThread Maybe handleError
handleError) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([ String
"TerminatingState "
              , ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId
              , String
" "
              , ThreadId m -> String
forall a. Show a => a -> String
show (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
              ]
              [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList (((Char
' ' Char -> ShowS
forall a. a -> [a] -> [a]
:) ShowS -> (handleError -> String) -> handleError -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. handleError -> String
forall a. Show a => a -> String
show) (handleError -> String) -> Maybe handleError -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe handleError
handleError))
    show (TerminatedState Maybe handleError
handleError) =
      [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String
"TerminatedState"]
              [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList (((Char
' ' Char -> ShowS
forall a. a -> [a] -> [a]
:) ShowS -> (handleError -> String) -> handleError -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. handleError -> String
forall a. Show a => a -> String
show) (handleError -> String) -> Maybe handleError -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe handleError
handleError))


getConnThread :: ConnectionState peerAddr handle handleError version m
              -> Maybe (Async m ())
getConnThread :: ConnectionState peerAddr handle handleError version m
-> Maybe (Async m ())
getConnThread ConnectionState peerAddr handle handleError version m
ReservedOutboundState                                     = Maybe (Async m ())
forall a. Maybe a
Nothing
getConnThread (UnnegotiatedState Provenance
_pr   ConnectionId peerAddr
_connId Async m ()
connThread)              = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread (OutboundUniState        ConnectionId peerAddr
_connId Async m ()
connThread handle
_handle )     = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread (OutboundDupState        ConnectionId peerAddr
_connId Async m ()
connThread handle
_handle TimeoutExpired
_te)  = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread (OutboundIdleState       ConnectionId peerAddr
_connId Async m ()
connThread handle
_handle DataFlow
_df)  = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread (InboundIdleState        ConnectionId peerAddr
_connId Async m ()
connThread handle
_handle DataFlow
_df)  = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread (InboundState            ConnectionId peerAddr
_connId Async m ()
connThread handle
_handle DataFlow
_df)  = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread (DuplexState             ConnectionId peerAddr
_connId Async m ()
connThread handle
_handle)      = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread (TerminatingState        ConnectionId peerAddr
_connId Async m ()
connThread Maybe handleError
_handleError) = Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
getConnThread TerminatedState {}                                        = Maybe (Async m ())
forall a. Maybe a
Nothing

-- | Get 'DataFlow' for a connection.  It returns 'Nowhere' if that connection
-- is either not yet created or in terminating state, 'There' for  unnegotiated
-- connections and 'Here' if the data flow is known.
--
getConnType :: ConnectionState peerAddr handle handleError version m
            -> Maybe ConnectionType
getConnType :: ConnectionState peerAddr handle handleError version m
-> Maybe ConnectionType
getConnType ConnectionState peerAddr handle handleError version m
ReservedOutboundState                                    = Maybe ConnectionType
forall a. Maybe a
Nothing
getConnType (UnnegotiatedState Provenance
pr  ConnectionId peerAddr
_connId Async m ()
_connThread)              = ConnectionType -> Maybe ConnectionType
forall a. a -> Maybe a
Just (Provenance -> ConnectionType
UnnegotiatedConn Provenance
pr)
getConnType (OutboundUniState      ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle)      = ConnectionType -> Maybe ConnectionType
forall a. a -> Maybe a
Just (Provenance -> DataFlow -> ConnectionType
NegotiatedConn Provenance
Outbound DataFlow
Unidirectional)
getConnType (OutboundDupState      ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle TimeoutExpired
_te)  = ConnectionType -> Maybe ConnectionType
forall a. a -> Maybe a
Just (Provenance -> DataFlow -> ConnectionType
NegotiatedConn Provenance
Outbound DataFlow
Duplex)
getConnType (OutboundIdleState     ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
df)   = ConnectionType -> Maybe ConnectionType
forall a. a -> Maybe a
Just (DataFlow -> ConnectionType
OutboundIdleConn DataFlow
df)
getConnType (InboundIdleState      ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
df)   = ConnectionType -> Maybe ConnectionType
forall a. a -> Maybe a
Just (DataFlow -> ConnectionType
InboundIdleConn DataFlow
df)
getConnType (InboundState          ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
df)   = ConnectionType -> Maybe ConnectionType
forall a. a -> Maybe a
Just (Provenance -> DataFlow -> ConnectionType
NegotiatedConn Provenance
Inbound DataFlow
df)
getConnType (DuplexState           ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle)      = ConnectionType -> Maybe ConnectionType
forall a. a -> Maybe a
Just ConnectionType
DuplexConn
getConnType (TerminatingState      ConnectionId peerAddr
_connId Async m ()
_connThread Maybe handleError
_handleError) = Maybe ConnectionType
forall a. Maybe a
Nothing
getConnType TerminatedState {}                                       = Maybe ConnectionType
forall a. Maybe a
Nothing


-- | Return 'True' if a connection is inbound.  This must agree with
-- 'connectionStateToCounters'.  Both are used for prunning.
--
isInboundConn :: ConnectionState peerAddr handle handleError version m -> Bool
isInboundConn :: ConnectionState peerAddr handle handleError version m -> Bool
isInboundConn ConnectionState peerAddr handle handleError version m
ReservedOutboundState                      = Bool
False
isInboundConn (UnnegotiatedState Provenance
pr ConnectionId peerAddr
_connId Async m ()
_connThread) = Provenance
pr Provenance -> Provenance -> Bool
forall a. Eq a => a -> a -> Bool
== Provenance
Inbound
isInboundConn OutboundUniState {}                        = Bool
False
isInboundConn OutboundDupState {}                        = Bool
False
isInboundConn OutboundIdleState {}                       = Bool
False
isInboundConn InboundIdleState {}                        = Bool
True
isInboundConn InboundState {}                            = Bool
True
isInboundConn DuplexState {}                             = Bool
True
isInboundConn TerminatingState {}                        = Bool
False
isInboundConn TerminatedState {}                         = Bool
False


abstractState :: MaybeUnknown (ConnectionState muxMode peerAddr m a b) -> AbstractState
abstractState :: MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState = \MaybeUnknown (ConnectionState muxMode peerAddr m a b)
s -> case MaybeUnknown (ConnectionState muxMode peerAddr m a b)
s of
    MaybeUnknown (ConnectionState muxMode peerAddr m a b)
Unknown  -> AbstractState
UnknownConnectionSt
    Race ConnectionState muxMode peerAddr m a b
s'  -> ConnectionState muxMode peerAddr m a b -> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
ConnectionState muxMode peerAddr m a b -> AbstractState
go ConnectionState muxMode peerAddr m a b
s'
    Known ConnectionState muxMode peerAddr m a b
s' -> ConnectionState muxMode peerAddr m a b -> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
ConnectionState muxMode peerAddr m a b -> AbstractState
go ConnectionState muxMode peerAddr m a b
s'
  where
    go :: ConnectionState muxMode peerAddr m a b -> AbstractState
    go :: ConnectionState muxMode peerAddr m a b -> AbstractState
go ReservedOutboundState {}       = AbstractState
ReservedOutboundSt
    go (UnnegotiatedState Provenance
pr ConnectionId muxMode
_ Async b ()
_)     = Provenance -> AbstractState
UnnegotiatedSt Provenance
pr
    go (OutboundUniState    ConnectionId muxMode
_ Async b ()
_ peerAddr
_)    = AbstractState
OutboundUniSt
    go (OutboundDupState    ConnectionId muxMode
_ Async b ()
_ peerAddr
_ TimeoutExpired
te) = TimeoutExpired -> AbstractState
OutboundDupSt TimeoutExpired
te
    go (OutboundIdleState ConnectionId muxMode
_ Async b ()
_ peerAddr
_ DataFlow
df)   = DataFlow -> AbstractState
OutboundIdleSt DataFlow
df
    go (InboundIdleState ConnectionId muxMode
_ Async b ()
_ peerAddr
_ DataFlow
df)    = DataFlow -> AbstractState
InboundIdleSt DataFlow
df
    go (InboundState     ConnectionId muxMode
_ Async b ()
_ peerAddr
_ DataFlow
df)    = DataFlow -> AbstractState
InboundSt DataFlow
df
    go DuplexState {}                 = AbstractState
DuplexSt
    go TerminatingState {}            = AbstractState
TerminatingSt
    go TerminatedState {}             = AbstractState
TerminatedSt


-- | The default value for 'cmTimeWaitTimeout'.
--
defaultTimeWaitTimeout :: DiffTime
defaultTimeWaitTimeout :: DiffTime
defaultTimeWaitTimeout = DiffTime
60

-- | Inactivity timeout.  It configures how long to wait since the local side
-- demoted remote peer to /cold/, before closing the connection.
--
defaultProtocolIdleTimeout :: DiffTime
defaultProtocolIdleTimeout :: DiffTime
defaultProtocolIdleTimeout = DiffTime
5

defaultResetTimeout :: DiffTime
defaultResetTimeout :: DiffTime
defaultResetTimeout = DiffTime
5


newtype PruneAction m = PruneAction { PruneAction m -> m ()
runPruneAction :: m () }

-- | Instruction used internally in @unregisterOutboundConnectionImpl@, e.g. in
-- the implementation of one of the two  @DemotedToCold^{dataFlow}_{Local}@
-- transitions.
--
data DemoteToColdLocal peerAddr handlerTrace handle handleError version m
    -- | Any @DemotedToCold@ transition which terminates the connection:
    -- @
    --   DemotedToCold^{Duplex}_{Local} : * -> TerminatingState
    -- @
    -- from the spec.
    --
    = DemotedToColdLocal      (ConnectionId peerAddr)
                              (Async m ())
                              (StrictTVar m (ConnectionState
                                              peerAddr handle
                                              handleError version m))
                             !(Transition (ConnectionState
                                            peerAddr handle
                                            handleError version m))

    -- | Any @DemoteToCold@ transition which does not terminate the connection, i.e.
    -- @
    --   DemotedToCold^{Duplex}_{Local} : OutboundState^\tau Duplex
    --                                  → InboundIdleState^\tau
    -- @
    -- or the case where the connection is already in 'TerminatingState' or
    -- 'TerminatedState'.
    --
    | DemoteToColdLocalNoop !(Maybe (Transition (ConnectionState
                                                  peerAddr handle
                                                  handleError version m)))
                            !AbstractState

    -- | Duplex connection was demoted, prune connections.
    --
    | PruneConnections       (PruneAction m)
                             -- ^ prune action

                            !(Either
                               (ConnectionState
                                 peerAddr handle
                                 handleError version m)
                               (Transition (ConnectionState
                                             peerAddr handle
                                             handleError version m))
                             )
                             -- ^ Left case is for when pruning tries to prune
                             -- the connection which triggered pruning, in this
                             -- case we do not want to trace a new transition.
                             --
                             -- Right case is for when the connection which
                             -- triggered pruning isn't pruned. In this case
                             -- we do want to trace a new transition.


    -- | Demote error.
    | DemoteToColdLocalError  (ConnectionManagerTrace peerAddr handlerTrace)
                             !AbstractState


-- | Entry point for using the connection manager.  This is a classic @with@ style
-- combinator, which cleans resources on exit of the callback (whether cleanly
-- or through an exception).
--
-- Including a connection (either inbound or outbound) is an idempotent
-- operation on connection manager state.  The connection manager will always
-- return the handle that was first to be included in its state.
--
-- Once an inbound connection is passed to the 'ConnectionManager', the manager
-- is responsible for the resource.
--
withConnectionManager
    :: forall (muxMode :: MuxMode) peerAddr socket handlerTrace handle handleError version m a.
       ( Monad              m
       , MonadLabelledSTM   m
       , MonadTraceSTM      m
       -- 'MonadFork' is only to get access to 'throwTo'
       , MonadFork          m
       , MonadAsync         m
       , MonadEvaluate      m
       , MonadFix           m
       , MonadMask          m
       , MonadMonotonicTime m
       , MonadThrow    (STM m)
       , MonadTimer         m

       , Ord      peerAddr
       , Show     peerAddr
       , Typeable peerAddr
       )
    => ConnectionManagerArguments handlerTrace socket peerAddr handle handleError version m
    -> ConnectionHandler  muxMode handlerTrace socket peerAddr handle handleError version m
    -- ^ Callback which runs in a thread dedicated for a given connection.
    -> (handleError -> HandleErrorType)
    -- ^ classify 'handleError's
    -> InResponderMode muxMode (ControlChannel m (ControlChannel.NewConnection peerAddr handle))
    -- ^ On outbound duplex connections we need to notify the server about
    -- a new connection.
    -> (ConnectionManager muxMode socket peerAddr handle handleError m -> m a)
    -- ^ Continuation which receives the 'ConnectionManager'.  It must not leak
    -- outside of scope of this callback.  Once it returns all resources
    -- will be closed.
    -> m a
withConnectionManager :: ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> ConnectionHandler
     muxMode handlerTrace socket peerAddr handle handleError version m
-> (handleError -> HandleErrorType)
-> InResponderMode
     muxMode (ControlChannel m (NewConnection peerAddr handle))
-> (ConnectionManager muxMode socket peerAddr handle handleError m
    -> m a)
-> m a
withConnectionManager ConnectionManagerArguments {
                          cmTracer :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
cmTracer    = Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer,
                          cmTrTracer :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Tracer
     m
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
cmTrTracer  = Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer,
                          cmMuxTracer :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Tracer m (WithMuxBearer (ConnectionId peerAddr) MuxTrace)
cmMuxTracer = Tracer m (WithMuxBearer (ConnectionId peerAddr) MuxTrace)
muxTracer,
                          Maybe peerAddr
cmIPv4Address :: Maybe peerAddr
cmIPv4Address :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Maybe peerAddr
cmIPv4Address,
                          Maybe peerAddr
cmIPv6Address :: Maybe peerAddr
cmIPv6Address :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Maybe peerAddr
cmIPv6Address,
                          peerAddr -> Maybe AddressType
cmAddressType :: peerAddr -> Maybe AddressType
cmAddressType :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> peerAddr -> Maybe AddressType
cmAddressType,
                          Snocket m socket peerAddr
cmSnocket :: Snocket m socket peerAddr
cmSnocket :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> Snocket m socket peerAddr
cmSnocket,
                          DiffTime
cmTimeWaitTimeout :: DiffTime
cmTimeWaitTimeout :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> DiffTime
cmTimeWaitTimeout,
                          DiffTime
cmOutboundIdleTimeout :: DiffTime
cmOutboundIdleTimeout :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> DiffTime
cmOutboundIdleTimeout,
                          version -> DataFlow
connectionDataFlow :: version -> DataFlow
connectionDataFlow :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> version -> DataFlow
connectionDataFlow,
                          PrunePolicy peerAddr (STM m)
cmPrunePolicy :: PrunePolicy peerAddr (STM m)
cmPrunePolicy :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> PrunePolicy peerAddr (STM m)
cmPrunePolicy,
                          AcceptedConnectionsLimit
cmConnectionsLimits :: AcceptedConnectionsLimit
cmConnectionsLimits :: forall handlerTrace socket peerAddr handle handleError version
       (m :: * -> *).
ConnectionManagerArguments
  handlerTrace socket peerAddr handle handleError version m
-> AcceptedConnectionsLimit
cmConnectionsLimits
                        }
                      ConnectionHandler {
                          WithMuxTuple
  muxMode
  (ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m)
connectionHandler :: forall (muxMode :: MuxMode) handlerTrace socket peerAddr handle
       handleError version (m :: * -> *).
ConnectionHandler
  muxMode handlerTrace socket peerAddr handle handleError version m
-> WithMuxTuple
     muxMode
     (ConnectionHandlerFn
        handlerTrace socket peerAddr handle handleError version m)
connectionHandler :: WithMuxTuple
  muxMode
  (ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m)
connectionHandler
                        }
                      handleError -> HandleErrorType
classifyHandleError
                      InResponderMode
  muxMode (ControlChannel m (NewConnection peerAddr handle))
inboundGovernorControlChannel
                      ConnectionManager muxMode socket peerAddr handle handleError m
-> m a
k = do
    ((FreshIdSupply m
freshIdSupply, StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar)
       ::  ( FreshIdSupply m
           , StrictTMVar m (ConnectionManagerState peerAddr handle handleError
                                                   version m)
           ))
      <- STM
  m
  (FreshIdSupply m,
   StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m))
-> m (FreshIdSupply m,
      StrictTMVar
        m (ConnectionManagerState peerAddr handle handleError version m))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (FreshIdSupply m,
    StrictTMVar
      m (ConnectionManagerState peerAddr handle handleError version m))
 -> m (FreshIdSupply m,
       StrictTMVar
         m (ConnectionManagerState peerAddr handle handleError version m)))
-> STM
     m
     (FreshIdSupply m,
      StrictTMVar
        m (ConnectionManagerState peerAddr handle handleError version m))
-> m (FreshIdSupply m,
      StrictTMVar
        m (ConnectionManagerState peerAddr handle handleError version m))
forall a b. (a -> b) -> a -> b
$  do
          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
v  <- ConnectionManagerState peerAddr handle handleError version m
-> STM
     m
     (StrictTMVar
        m (ConnectionManagerState peerAddr handle handleError version m))
forall (m :: * -> *) a. MonadSTM m => a -> STM m (StrictTMVar m a)
newTMVar ConnectionManagerState peerAddr handle handleError version m
forall k a. Map k a
Map.empty
          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> String -> STM m ()
forall (m :: * -> *) a.
MonadLabelledSTM m =>
StrictTMVar m a -> String -> STM m ()
labelTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
v String
"cm-state"
          Proxy m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> (Maybe
      (Maybe
         (ConnectionManagerState peerAddr handle handleError version m))
    -> Maybe
         (ConnectionManagerState peerAddr handle handleError version m)
    -> InspectMonad m TraceValue)
-> STM m ()
forall (m :: * -> *) (proxy :: (* -> *) -> *) a.
MonadTraceSTM m =>
proxy m
-> StrictTMVar m a
-> (Maybe (Maybe a) -> Maybe a -> InspectMonad m TraceValue)
-> STM m ()
traceTMVar (Proxy m
forall k (t :: k). Proxy t
Proxy :: Proxy m) StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
v
                   ((Maybe
    (Maybe
       (ConnectionManagerState peerAddr handle handleError version m))
  -> Maybe
       (ConnectionManagerState peerAddr handle handleError version m)
  -> InspectMonad m TraceValue)
 -> STM m ())
-> (Maybe
      (Maybe
         (ConnectionManagerState peerAddr handle handleError version m))
    -> Maybe
         (ConnectionManagerState peerAddr handle handleError version m)
    -> InspectMonad m TraceValue)
-> STM m ()
forall a b. (a -> b) -> a -> b
$ \Maybe
  (Maybe
     (ConnectionManagerState peerAddr handle handleError version m))
old Maybe
  (ConnectionManagerState peerAddr handle handleError version m)
new ->
                     case (Maybe
  (Maybe
     (ConnectionManagerState peerAddr handle handleError version m))
old, Maybe
  (ConnectionManagerState peerAddr handle handleError version m)
new) of
                       (Maybe
  (Maybe
     (ConnectionManagerState peerAddr handle handleError version m))
Nothing, Maybe
  (ConnectionManagerState peerAddr handle handleError version m)
_)             -> TraceValue -> InspectMonad m TraceValue
forall (f :: * -> *) a. Applicative f => a -> f a
pure TraceValue
DontTrace
                       -- taken
                       (Just (Just ConnectionManagerState peerAddr handle handleError version m
_), Maybe
  (ConnectionManagerState peerAddr handle handleError version m)
Nothing) -> TraceValue -> InspectMonad m TraceValue
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> TraceValue
TraceString String
"cm-state: taken")
                       -- released
                       (Just Maybe
  (ConnectionManagerState peerAddr handle handleError version m)
Nothing,  Just ConnectionManagerState peerAddr handle handleError version m
_)  -> TraceValue -> InspectMonad m TraceValue
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> TraceValue
TraceString String
"cm-state: released")
                       (Maybe
  (Maybe
     (ConnectionManagerState peerAddr handle handleError version m))
_, Maybe
  (ConnectionManagerState peerAddr handle handleError version m)
_)                   -> TraceValue -> InspectMonad m TraceValue
forall (f :: * -> *) a. Applicative f => a -> f a
pure TraceValue
DontTrace

          FreshIdSupply m
freshIdSupply <- Proxy m -> STM m (FreshIdSupply m)
forall (m :: * -> *).
MonadSTM m =>
Proxy m -> STM m (FreshIdSupply m)
newFreshIdSupply (Proxy m
forall k (t :: k). Proxy t
Proxy :: Proxy m)
          (FreshIdSupply m,
 StrictTMVar
   m (ConnectionManagerState peerAddr handle handleError version m))
-> STM
     m
     (FreshIdSupply m,
      StrictTMVar
        m (ConnectionManagerState peerAddr handle handleError version m))
forall (m :: * -> *) a. Monad m => a -> m a
return (FreshIdSupply m
freshIdSupply, StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
v)

    let readState
          :: m (Map peerAddr AbstractState)
        readState :: m (Map peerAddr AbstractState)
readState =
          STM m (Map peerAddr AbstractState)
-> m (Map peerAddr AbstractState)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (Map peerAddr AbstractState)
 -> m (Map peerAddr AbstractState))
-> STM m (Map peerAddr AbstractState)
-> m (Map peerAddr AbstractState)
forall a b. (a -> b) -> a -> b
$ do
              ConnectionManagerState peerAddr handle handleError version m
state <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
              (MutableConnState peerAddr handle handleError version m
 -> STM m AbstractState)
-> ConnectionManagerState peerAddr handle handleError version m
-> STM m (Map peerAddr AbstractState)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ( (ConnectionState peerAddr handle handleError version m
 -> AbstractState)
-> STM m (ConnectionState peerAddr handle handleError version m)
-> STM m AbstractState
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (MaybeUnknown
   (ConnectionState peerAddr handle handleError version m)
 -> AbstractState)
-> (ConnectionState peerAddr handle handleError version m
    -> MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
-> ConnectionState peerAddr handle handleError version m
-> AbstractState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known)
                       (STM m (ConnectionState peerAddr handle handleError version m)
 -> STM m AbstractState)
-> (MutableConnState peerAddr handle handleError version m
    -> STM m (ConnectionState peerAddr handle handleError version m))
-> MutableConnState peerAddr handle handleError version m
-> STM m AbstractState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar
                       (StrictTVar
   m (ConnectionState peerAddr handle handleError version m)
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> (MutableConnState peerAddr handle handleError version m
    -> StrictTVar
         m (ConnectionState peerAddr handle handleError version m))
-> MutableConnState peerAddr handle handleError version m
-> STM m (ConnectionState peerAddr handle handleError version m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar
                       )
                       ConnectionManagerState peerAddr handle handleError version m
state

        connectionManager :: ConnectionManager muxMode socket peerAddr
                                               handle handleError m
        connectionManager :: ConnectionManager muxMode socket peerAddr handle handleError m
connectionManager =
          case WithMuxTuple
  muxMode
  (ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m)
connectionHandler of
            WithInitiatorMode ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
outboundHandler ->
              ConnectionManager :: forall (muxMode :: MuxMode) socket peerAddr handle handleError
       (m :: * -> *).
WithMuxMode
  muxMode
  (OutboundConnectionManager
     muxMode socket peerAddr handle handleError m)
  (InboundConnectionManager
     muxMode socket peerAddr handle handleError m)
-> m (Map peerAddr AbstractState)
-> ConnectionManager muxMode socket peerAddr handle handleError m
ConnectionManager {
                getConnectionManager :: WithMuxMode
  muxMode
  (OutboundConnectionManager
     muxMode socket peerAddr handle handleError m)
  (InboundConnectionManager
     muxMode socket peerAddr handle handleError m)
getConnectionManager =
                  OutboundConnectionManager
  muxMode socket peerAddr handle handleError m
-> WithMuxMode
     'InitiatorMode
     (OutboundConnectionManager
        muxMode socket peerAddr handle handleError m)
     (InboundConnectionManager
        muxMode socket peerAddr handle handleError m)
forall a b. a -> WithMuxMode 'InitiatorMode a b
WithInitiatorMode
                    OutboundConnectionManager :: forall (muxMode :: MuxMode) peerAddr handle handleError
       (m :: * -> *) socket.
(HasInitiator muxMode ~ 'True) =>
RequestOutboundConnection peerAddr handle handleError m
-> (peerAddr -> m (OperationResult AbstractState))
-> OutboundConnectionManager
     muxMode socket peerAddr handle handleError m
OutboundConnectionManager {
                        ocmRequestConnection :: RequestOutboundConnection peerAddr handle handleError m
ocmRequestConnection =
                          HasCallStack =>
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> RequestOutboundConnection peerAddr handle handleError m
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> RequestOutboundConnection peerAddr handle handleError m
requestOutboundConnectionImpl FreshIdSupply m
freshIdSupply StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                                                        ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
outboundHandler,
                        ocmUnregisterConnection :: peerAddr -> m (OperationResult AbstractState)
ocmUnregisterConnection =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
unregisterOutboundConnectionImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                      },
                m (Map peerAddr AbstractState)
readState :: m (Map peerAddr AbstractState)
readState :: m (Map peerAddr AbstractState)
readState
              }

            WithResponderMode ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
inboundHandler ->
              ConnectionManager :: forall (muxMode :: MuxMode) socket peerAddr handle handleError
       (m :: * -> *).
WithMuxMode
  muxMode
  (OutboundConnectionManager
     muxMode socket peerAddr handle handleError m)
  (InboundConnectionManager
     muxMode socket peerAddr handle handleError m)
-> m (Map peerAddr AbstractState)
-> ConnectionManager muxMode socket peerAddr handle handleError m
ConnectionManager {
                getConnectionManager :: WithMuxMode
  muxMode
  (OutboundConnectionManager
     muxMode socket peerAddr handle handleError m)
  (InboundConnectionManager
     muxMode socket peerAddr handle handleError m)
getConnectionManager =
                  InboundConnectionManager
  muxMode socket peerAddr handle handleError m
-> WithMuxMode
     'ResponderMode
     (OutboundConnectionManager
        muxMode socket peerAddr handle handleError m)
     (InboundConnectionManager
        muxMode socket peerAddr handle handleError m)
forall b a. b -> WithMuxMode 'ResponderMode a b
WithResponderMode
                    InboundConnectionManager :: forall (muxMode :: MuxMode) socket peerAddr handle handleError
       (m :: * -> *).
(HasResponder muxMode ~ 'True) =>
IncludeInboundConnection socket peerAddr handle handleError m
-> (peerAddr -> m (OperationResult DemotedToColdRemoteTr))
-> (peerAddr -> m (OperationResult AbstractState))
-> (peerAddr -> m (OperationResult AbstractState))
-> STM m Int
-> InboundConnectionManager
     muxMode socket peerAddr handle handleError m
InboundConnectionManager {
                        icmIncludeConnection :: IncludeInboundConnection socket peerAddr handle handleError m
icmIncludeConnection =
                          HasCallStack =>
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> IncludeInboundConnection socket peerAddr handle handleError m
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> IncludeInboundConnection socket peerAddr handle handleError m
includeInboundConnectionImpl FreshIdSupply m
freshIdSupply StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                                                       ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
inboundHandler,
                        icmUnregisterConnection :: peerAddr -> m (OperationResult DemotedToColdRemoteTr)
icmUnregisterConnection =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult DemotedToColdRemoteTr)
unregisterInboundConnectionImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar,
                        icmPromotedToWarmRemote :: peerAddr -> m (OperationResult AbstractState)
icmPromotedToWarmRemote =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
promotedToWarmRemoteImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar,
                        icmDemotedToColdRemote :: peerAddr -> m (OperationResult AbstractState)
icmDemotedToColdRemote =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
demotedToColdRemoteImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar,
                        icmNumberOfConnections :: STM m Int
icmNumberOfConnections =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar STM
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> STM m Int)
-> STM m Int
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ConnectionManagerState peerAddr handle handleError version m
-> STM m Int
countIncomingConnections
                      },
                m (Map peerAddr AbstractState)
readState :: m (Map peerAddr AbstractState)
readState :: m (Map peerAddr AbstractState)
readState
              }

            WithInitiatorResponderMode ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
outboundHandler ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
inboundHandler ->
              ConnectionManager :: forall (muxMode :: MuxMode) socket peerAddr handle handleError
       (m :: * -> *).
WithMuxMode
  muxMode
  (OutboundConnectionManager
     muxMode socket peerAddr handle handleError m)
  (InboundConnectionManager
     muxMode socket peerAddr handle handleError m)
-> m (Map peerAddr AbstractState)
-> ConnectionManager muxMode socket peerAddr handle handleError m
ConnectionManager {
                getConnectionManager :: WithMuxMode
  muxMode
  (OutboundConnectionManager
     muxMode socket peerAddr handle handleError m)
  (InboundConnectionManager
     muxMode socket peerAddr handle handleError m)
getConnectionManager =
                  OutboundConnectionManager
  muxMode socket peerAddr handle handleError m
-> InboundConnectionManager
     muxMode socket peerAddr handle handleError m
-> WithMuxMode
     'InitiatorResponderMode
     (OutboundConnectionManager
        muxMode socket peerAddr handle handleError m)
     (InboundConnectionManager
        muxMode socket peerAddr handle handleError m)
forall a b. a -> b -> WithMuxMode 'InitiatorResponderMode a b
WithInitiatorResponderMode
                    OutboundConnectionManager :: forall (muxMode :: MuxMode) peerAddr handle handleError
       (m :: * -> *) socket.
(HasInitiator muxMode ~ 'True) =>
RequestOutboundConnection peerAddr handle handleError m
-> (peerAddr -> m (OperationResult AbstractState))
-> OutboundConnectionManager
     muxMode socket peerAddr handle handleError m
OutboundConnectionManager {
                        ocmRequestConnection :: RequestOutboundConnection peerAddr handle handleError m
ocmRequestConnection =
                          HasCallStack =>
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> RequestOutboundConnection peerAddr handle handleError m
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> RequestOutboundConnection peerAddr handle handleError m
requestOutboundConnectionImpl FreshIdSupply m
freshIdSupply StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                                                        ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
outboundHandler,
                        ocmUnregisterConnection :: peerAddr -> m (OperationResult AbstractState)
ocmUnregisterConnection =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
unregisterOutboundConnectionImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                      }
                    InboundConnectionManager :: forall (muxMode :: MuxMode) socket peerAddr handle handleError
       (m :: * -> *).
(HasResponder muxMode ~ 'True) =>
IncludeInboundConnection socket peerAddr handle handleError m
-> (peerAddr -> m (OperationResult DemotedToColdRemoteTr))
-> (peerAddr -> m (OperationResult AbstractState))
-> (peerAddr -> m (OperationResult AbstractState))
-> STM m Int
-> InboundConnectionManager
     muxMode socket peerAddr handle handleError m
InboundConnectionManager {
                        icmIncludeConnection :: IncludeInboundConnection socket peerAddr handle handleError m
icmIncludeConnection =
                          HasCallStack =>
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> IncludeInboundConnection socket peerAddr handle handleError m
FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> IncludeInboundConnection socket peerAddr handle handleError m
includeInboundConnectionImpl FreshIdSupply m
freshIdSupply StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                                                       ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
inboundHandler,
                        icmUnregisterConnection :: peerAddr -> m (OperationResult DemotedToColdRemoteTr)
icmUnregisterConnection =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult DemotedToColdRemoteTr)
unregisterInboundConnectionImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar,
                        icmPromotedToWarmRemote :: peerAddr -> m (OperationResult AbstractState)
icmPromotedToWarmRemote =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
promotedToWarmRemoteImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar,
                        icmDemotedToColdRemote :: peerAddr -> m (OperationResult AbstractState)
icmDemotedToColdRemote =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
demotedToColdRemoteImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar,
                        icmNumberOfConnections :: STM m Int
icmNumberOfConnections =
                          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar STM
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> STM m Int)
-> STM m Int
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ConnectionManagerState peerAddr handle handleError version m
-> STM m Int
countIncomingConnections
                      },
                m (Map peerAddr AbstractState)
readState :: m (Map peerAddr AbstractState)
readState :: m (Map peerAddr AbstractState)
readState
              }

    ConnectionManager muxMode socket peerAddr handle handleError m
-> m a
k ConnectionManager muxMode socket peerAddr handle handleError m
connectionManager
      -- Since this exception handler is blocking it might receive exceptions
      -- during its execution, which we want to avoid, so we wrap it around
      -- uninterruptibleMask_.
      m a -> m () -> m a
forall (m :: * -> *) a b. MonadThrow m => m a -> m b -> m a
`finally` m () -> m ()
forall (m :: * -> *) a. MonadMask m => m a -> m a
uninterruptibleMask_ (do
        Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionManagerTrace peerAddr handlerTrace
TrShutdown

        ConnectionManagerState peerAddr handle handleError version m
state <- STM
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m (ConnectionManagerState peerAddr handle handleError version m)
 -> m (ConnectionManagerState
         peerAddr handle handleError version m))
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
-> m (ConnectionManagerState peerAddr handle handleError version m)
forall a b. (a -> b) -> a -> b
$ StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
        -- Spawning one thread for each connection cleanup avoids spending time
        -- waiting for locks and cleanup logic that could delay closing the
        -- connections and making us not respecting certain timeouts.
        [Async m ()]
asyncs <- Map peerAddr (Async m ()) -> [Async m ()]
forall k a. Map k a -> [a]
Map.elems
          (Map peerAddr (Async m ()) -> [Async m ()])
-> m (Map peerAddr (Async m ())) -> m [Async m ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (peerAddr
 -> MutableConnState peerAddr handle handleError version m
 -> m (Maybe (Async m ())))
-> ConnectionManagerState peerAddr handle handleError version m
-> m (Map peerAddr (Async m ()))
forall (f :: * -> *) k a b.
Applicative f =>
(k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)
Map.traverseMaybeWithKey
          (\peerAddr
peerAddr MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar } -> do
            -- cleanup handler for that thread will close socket associated
            -- with the thread.  We put each connection in 'TerminatedState' to
            -- try that none of the connection threads will enter
            -- 'TerminatingState' (and thus delay shutdown for 'tcp_WAIT_TIME'
            -- seconds) when receiving the 'AsyncCancelled' exception. However,
            -- we can have a race between the finally handler and the `cleanup`
            -- callback. If the finally block loses the race, the received
            -- 'AsyncCancelled' should interrupt the 'threadDelay'.
            --
            (ConnectionState peerAddr handle handleError version m
connState, TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
tr, Bool
shouldTrace) <- STM
  m
  (ConnectionState peerAddr handle handleError version m,
   TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m),
   Bool)
-> m (ConnectionState peerAddr handle handleError version m,
      TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m),
      Bool)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (ConnectionState peerAddr handle handleError version m,
    TransitionTrace
      peerAddr (ConnectionState peerAddr handle handleError version m),
    Bool)
 -> m (ConnectionState peerAddr handle handleError version m,
       TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m),
       Bool))
-> STM
     m
     (ConnectionState peerAddr handle handleError version m,
      TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m),
      Bool)
-> m (ConnectionState peerAddr handle handleError version m,
      TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m),
      Bool)
forall a b. (a -> b) -> a -> b
$ do
              ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
              let connState' :: ConnectionState peerAddr handle handleError version m
connState' = Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing
                  tr :: TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
tr = peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState')
                  absConnState :: AbstractState
absConnState = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
                  shouldTrace :: Bool
shouldTrace = AbstractState
absConnState AbstractState -> AbstractState -> Bool
forall a. Eq a => a -> a -> Bool
/= AbstractState
TerminatedSt

              StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
              (ConnectionState peerAddr handle handleError version m,
 TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m),
 Bool)
-> STM
     m
     (ConnectionState peerAddr handle handleError version m,
      TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m),
      Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionState peerAddr handle handleError version m
connState, TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
tr, Bool
shouldTrace)

            Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
shouldTrace (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
              Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
tr
            -- using 'throwTo' here, since we want to block only until connection
            -- handler thread receives an exception so as to not take up extra
            -- time and making us go above timeout schedules.
            (Async m () -> m (Async m ()))
-> Maybe (Async m ()) -> m (Maybe (Async m ()))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
              (\Async m ()
thread -> do
                ThreadId m -> AsyncCancelled -> m ()
forall (m :: * -> *) e.
(MonadFork m, Exception e) =>
ThreadId m -> e -> m ()
throwTo (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
thread) AsyncCancelled
AsyncCancelled
                Async m () -> m (Async m ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure Async m ()
thread
              )
              (ConnectionState peerAddr handle handleError version m
-> Maybe (Async m ())
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
-> Maybe (Async m ())
getConnThread ConnectionState peerAddr handle handleError version m
connState)
          ) ConnectionManagerState peerAddr handle handleError version m
state

        STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ LastToFinishM (STM m) () -> STM m ()
forall (m :: * -> *) a. LastToFinishM m a -> m a
runLastToFinishM
                   (LastToFinishM (STM m) () -> STM m ())
-> LastToFinishM (STM m) () -> STM m ()
forall a b. (a -> b) -> a -> b
$ (Async m () -> LastToFinishM (STM m) ())
-> [Async m ()] -> LastToFinishM (STM m) ()
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (STM m () -> LastToFinishM (STM m) ()
forall (m :: * -> *) a. m a -> LastToFinishM m a
LastToFinishM (STM m () -> LastToFinishM (STM m) ())
-> (STM m (Either SomeException ()) -> STM m ())
-> STM m (Either SomeException ())
-> LastToFinishM (STM m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STM m (Either SomeException ()) -> STM m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (STM m (Either SomeException ()) -> LastToFinishM (STM m) ())
-> (Async m () -> STM m (Either SomeException ()))
-> Async m ()
-> LastToFinishM (STM m) ()
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Async m () -> STM m (Either SomeException ())
forall (m :: * -> *) a.
MonadAsync m =>
Async m a -> STM m (Either SomeException a)
waitCatchSTM) [Async m ()]
asyncs
      )
  where
    traceCounters :: StrictTMVar m (ConnectionManagerState peerAddr handle handleError version m) -> m ()
    traceCounters :: StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar = do
      Map
  peerAddr (ConnectionState peerAddr handle handleError version m)
mState <- STM
  m
  (Map
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> m (Map
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Map
      peerAddr (ConnectionState peerAddr handle handleError version m))
 -> m (Map
         peerAddr (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Map
        peerAddr (ConnectionState peerAddr handle handleError version m))
-> m (Map
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a b. (a -> b) -> a -> b
$ StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar STM
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> STM
         m
         (Map
            peerAddr (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Map
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (MutableConnState peerAddr handle handleError version m
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> ConnectionManagerState peerAddr handle handleError version m
-> STM
     m
     (Map
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (StrictTVar
   m (ConnectionState peerAddr handle handleError version m)
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> (MutableConnState peerAddr handle handleError version m
    -> StrictTVar
         m (ConnectionState peerAddr handle handleError version m))
-> MutableConnState peerAddr handle handleError version m
-> STM m (ConnectionState peerAddr handle handleError version m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar)
      Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (ConnectionManagerCounters
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionManagerCounters
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionManagerCounters (Map
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> ConnectionManagerCounters
forall peerAddr handle handleError version (m :: * -> *).
Map
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> ConnectionManagerCounters
connectionManagerStateToCounters Map
  peerAddr (ConnectionState peerAddr handle handleError version m)
mState))

    countIncomingConnections
        :: ConnectionManagerState peerAddr handle handleError version m
        -> STM m Int
    countIncomingConnections :: ConnectionManagerState peerAddr handle handleError version m
-> STM m Int
countIncomingConnections ConnectionManagerState peerAddr handle handleError version m
st =
          ConnectionManagerCounters -> Int
inboundConns
        (ConnectionManagerCounters -> Int)
-> (Map
      peerAddr (ConnectionState peerAddr handle handleError version m)
    -> ConnectionManagerCounters)
-> Map
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> ConnectionManagerCounters
forall peerAddr handle handleError version (m :: * -> *).
Map
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> ConnectionManagerCounters
connectionManagerStateToCounters
      (Map
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> Int)
-> STM
     m
     (Map
        peerAddr (ConnectionState peerAddr handle handleError version m))
-> STM m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableConnState peerAddr handle handleError version m
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> ConnectionManagerState peerAddr handle handleError version m
-> STM
     m
     (Map
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (StrictTVar
   m (ConnectionState peerAddr handle handleError version m)
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> (MutableConnState peerAddr handle handleError version m
    -> StrictTVar
         m (ConnectionState peerAddr handle handleError version m))
-> MutableConnState peerAddr handle handleError version m
-> STM m (ConnectionState peerAddr handle handleError version m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar) ConnectionManagerState peerAddr handle handleError version m
st


    -- Fork connection thread.
    --
    -- TODO: We don't have 'MonadFix' instance for 'IOSim', so we cannot
    -- directly pass 'connVar' (which requires @Async ()@ returned by this
    -- function.  If we had 'MonadFix' at hand We could then also elegantly
    -- eliminate 'PromiseWriter'.
    forkConnectionHandler
      :: StrictTMVar m (ConnectionManagerState peerAddr handle handleError version m)
      -> MutableConnState peerAddr handle handleError version m
      -> socket
      -> ConnectionId peerAddr
      -> PromiseWriter m (Either handleError (handle, version))
      -> ConnectionHandlerFn handlerTrace socket peerAddr handle handleError version m
      -> m (Async m ())
    forkConnectionHandler :: StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> MutableConnState peerAddr handle handleError version m
-> socket
-> ConnectionId peerAddr
-> PromiseWriter m (Either handleError (handle, version))
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> m (Async m ())
forkConnectionHandler StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                          mutableConnState :: MutableConnState peerAddr handle handleError version m
mutableConnState@MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar }
                          socket
socket
                          connId :: ConnectionId peerAddr
connId@ConnectionId { remoteAddress :: forall addr. ConnectionId addr -> addr
remoteAddress = peerAddr
peerAddr }
                          PromiseWriter m (Either handleError (handle, version))
writer
                          ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
handler =
        ((forall a. m a -> m a) -> m (Async m ())) -> m (Async m ())
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m (Async m ())) -> m (Async m ()))
-> ((forall a. m a -> m a) -> m (Async m ())) -> m (Async m ())
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
unmask -> m () -> m (Async m ())
forall (m :: * -> *) a. MonadAsync m => m a -> m (Async m a)
async (m () -> m (Async m ())) -> m () -> m (Async m ())
forall a b. (a -> b) -> a -> b
$ do
          MaskedAction m () -> (forall a. m a -> m a) -> m ()
forall (m :: * -> *) a.
MaskedAction m a -> (forall x. m x -> m x) -> m a
runWithUnmask
            (ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
handler socket
socket PromiseWriter m (Either handleError (handle, version))
writer
                     (ConnectionId peerAddr
-> handlerTrace -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionId peerAddr
-> handlerTrace -> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionHandler ConnectionId peerAddr
connId (handlerTrace -> ConnectionManagerTrace peerAddr handlerTrace)
-> Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> Tracer m handlerTrace
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
`contramap` Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer)
                     ConnectionId peerAddr
connId
                     (\DiffTime
bearerTimeout ->
                       Snocket m socket peerAddr
-> DiffTime -> Tracer m MuxTrace -> socket -> m (MuxBearer m)
forall (m :: * -> *) fd addr.
Snocket m fd addr
-> DiffTime -> Tracer m MuxTrace -> fd -> m (MuxBearer m)
toBearer
                         Snocket m socket peerAddr
cmSnocket
                         DiffTime
bearerTimeout
                         (ConnectionId peerAddr
-> MuxTrace -> WithMuxBearer (ConnectionId peerAddr) MuxTrace
forall peerid a. peerid -> a -> WithMuxBearer peerid a
WithMuxBearer ConnectionId peerAddr
connId (MuxTrace -> WithMuxBearer (ConnectionId peerAddr) MuxTrace)
-> Tracer m (WithMuxBearer (ConnectionId peerAddr) MuxTrace)
-> Tracer m MuxTrace
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
`contramap` Tracer m (WithMuxBearer (ConnectionId peerAddr) MuxTrace)
muxTracer)))
            forall a. m a -> m a
unmask
          m () -> m () -> m ()
forall (m :: * -> *) a b. MonadThrow m => m a -> m b -> m a
`finally` m ()
cleanup
      where
        cleanup :: m ()
        cleanup :: m ()
cleanup =
          -- We must ensure that we update 'connVar',
          -- `requestOutboundConnection` might be blocked on it awaiting for:
          -- - handshake negotiation; or
          -- - `Terminate: TerminatingState → TerminatedState` transition.
          -- That's why we use 'uninterruptibleMask'. Note that this cleanup
          -- function after all is interruptible, because we unmask async
          -- exceptions around 'threadDelay', but even if an async exception
          -- hits there we will update `connVar`.
          ((forall a. m a -> m a) -> m ()) -> m ()
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
uninterruptibleMask (((forall a. m a -> m a) -> m ()) -> m ())
-> ((forall a. m a -> m a) -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
unmask -> do
            Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionCleanup ConnectionId peerAddr
connId)
            Either
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
eTransition <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> m (ConnectionManagerState peerAddr handle handleError version m,
          Either
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))
            (Transition'
               (MaybeUnknown
                  (ConnectionState peerAddr handle handleError version m)))))
-> m (Either
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a b.
(MonadEvaluate m, MonadMask m, MonadSTM m) =>
StrictTMVar m a -> (a -> m (a, b)) -> m b
modifyTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar ((ConnectionManagerState peerAddr handle handleError version m
  -> m (ConnectionManagerState peerAddr handle handleError version m,
        Either
          (MaybeUnknown
             (ConnectionState peerAddr handle handleError version m))
          (Transition'
             (MaybeUnknown
                (ConnectionState peerAddr handle handleError version m)))))
 -> m (Either
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> (ConnectionManagerState peerAddr handle handleError version m
    -> m (ConnectionManagerState peerAddr handle handleError version m,
          Either
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))
            (Transition'
               (MaybeUnknown
                  (ConnectionState peerAddr handle handleError version m)))))
-> m (Either
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ \ConnectionManagerState peerAddr handle handleError version m
state -> do
              Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
eTransition <- STM
  m
  (Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))))
-> m (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Either
      (Maybe
         (TransitionTrace
            peerAddr (ConnectionState peerAddr handle handleError version m)))
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
 -> m (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
-> m (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ do
                ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing
                    transition :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition = ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    transitionTrace :: TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace = peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition
                case ConnectionState peerAddr handle handleError version m
connState of
                  ConnectionState peerAddr handle handleError version m
ReservedOutboundState -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  UnnegotiatedState {} -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  OutboundUniState {} -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  OutboundDupState {} -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  OutboundIdleState {} -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  InboundIdleState {} -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  InboundState {} -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  DuplexState {} -> do
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. a -> Maybe a
Just TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
transitionTrace)
                  TerminatingState {} -> do
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. b -> Either a b
Right Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition
                  TerminatedState {} ->
                    Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either
   (Maybe
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m)))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m)))
 -> STM
      m
      (Either
         (Maybe
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m)))
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (Maybe
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m)))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> Either
     (Maybe
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m)))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
forall a. Maybe a
Nothing

              case Either
  (Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m)))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
eTransition of
                Left Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
mbTransition -> do
                  (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer) Maybe
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
mbTransition
                  Snocket m socket peerAddr -> socket -> m ()
forall (m :: * -> *) fd addr. Snocket m fd addr -> fd -> m ()
close Snocket m socket peerAddr
cmSnocket socket
socket
                  (ConnectionManagerState peerAddr handle handleError version m,
 Either
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))))
-> m (ConnectionManagerState peerAddr handle handleError version m,
      Either
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return ( peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state
                         , MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> Either
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing))
                         )
                Right Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition -> do
                  Snocket m socket peerAddr -> socket -> m ()
forall (m :: * -> *) fd addr. Snocket m fd addr -> fd -> m ()
close Snocket m socket peerAddr
cmSnocket socket
socket
                  (ConnectionManagerState peerAddr handle handleError version m,
 Either
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))))
-> m (ConnectionManagerState peerAddr handle handleError version m,
      Either
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return ( ConnectionManagerState peerAddr handle handleError version m
state
                         , Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Either
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. b -> Either a b
Right Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition
                         )

            case Either
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
eTransition of
              Left MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
Unknown -> do
                -- TODO: this only happens because we read 'mConnVar' from
                -- 'stateVar', if we have 'MonadFix' instance we could access it
                -- directly which would reduce this case.
                Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrUnknownConnection ConnectionId peerAddr
connId)
                StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

              Left connState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
connState@Known {} -> do
                Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr
                                      Transition :: forall state. state -> state -> Transition' state
Transition
                                         { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
connState
                                         , toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown
                                         })
                StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
              -- This case is impossible to reach since the previous atomically block
              -- does not return the 'Race' constructor.
              -- TODO: Make this pattern match impossible.
              Left MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
_ -> String -> m ()
forall a. HasCallStack => String -> a
error String
"connection cleanup handler: impossible happened"
              Right Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition ->
                do Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionTimeWait ConnectionId peerAddr
connId)
                   Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (DiffTime
cmTimeWaitTimeout DiffTime -> DiffTime -> Bool
forall a. Ord a => a -> a -> Bool
> DiffTime
0) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
                     let -- make sure we wait at least 'cmTimeWaitTimeout', we
                         -- ignore all 'AsyncCancelled' exceptions.
                         forceThreadDelay :: DiffTime -> m ()
forceThreadDelay DiffTime
delay | DiffTime
delay DiffTime -> DiffTime -> Bool
forall a. Ord a => a -> a -> Bool
<= DiffTime
0 = () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
                         forceThreadDelay DiffTime
delay = do
                           Time
t <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
                           m () -> m ()
forall a. m a -> m a
unmask (DiffTime -> m ()
forall (m :: * -> *). MonadDelay m => DiffTime -> m ()
threadDelay DiffTime
delay)
                             m () -> (SomeException -> m ()) -> m ()
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` \SomeException
e ->
                                case SomeException -> Maybe AsyncCancelled
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e
                                of Just (AsyncCancelled
AsyncCancelled) -> do
                                     Time
t' <- m Time
forall (m :: * -> *). MonadMonotonicTime m => m Time
getMonotonicTime
                                     DiffTime -> m ()
forceThreadDelay (DiffTime
delay DiffTime -> DiffTime -> DiffTime
forall a. Num a => a -> a -> a
- Time
t' Time -> Time -> DiffTime
`diffTime` Time
t)
                                   Maybe AsyncCancelled
_ -> SomeException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO SomeException
e
                     in DiffTime -> m ()
forceThreadDelay DiffTime
cmTimeWaitTimeout
                m () -> m () -> m ()
forall (m :: * -> *) a b. MonadThrow m => m a -> m b -> m a
`finally` do
                  -- We must ensure that we update 'connVar',
                  -- `requestOutboundConnection` might be blocked on it awaiting for:
                  -- - handshake negotiation; or
                  -- - `Terminate: TerminatingState → TerminatedState` transition.
                  Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionTimeWaitDone ConnectionId peerAddr
connId)

                  [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
trs <- STM
  m
  [Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))]
-> m [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
 -> m [Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))])
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
-> m [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. (a -> b) -> a -> b
$ do
                    ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                    let transition' :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition' = Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState }
                        shouldTrace :: Bool
shouldTrace = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
                                   AbstractState -> AbstractState -> Bool
forall a. Eq a => a -> a -> Bool
/= AbstractState
TerminatedSt
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing)
                    --  We have to be careful when deleting it from
                    --  'ConnectionManagerState'.
                    Bool
updated <-
                      StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> (ConnectionManagerState peerAddr handle handleError version m,
        Bool))
-> STM m Bool
forall (m :: * -> *) a b.
MonadSTM m =>
StrictTMVar m a -> (a -> (a, b)) -> STM m b
modifyTMVarPure
                        StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                        ( \ConnectionManagerState peerAddr handle handleError version m
state ->
                          case peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state of
                            Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> (ConnectionManagerState peerAddr handle handleError version m
state, Bool
False)
                            Just MutableConnState peerAddr handle handleError version m
v  ->
                              if MutableConnState peerAddr handle handleError version m
mutableConnState MutableConnState peerAddr handle handleError version m
-> MutableConnState peerAddr handle handleError version m -> Bool
forall a. Eq a => a -> a -> Bool
== MutableConnState peerAddr handle handleError version m
v
                                then (peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state , Bool
True)
                                else (ConnectionManagerState peerAddr handle handleError version m
state                     , Bool
False)
                        )

                    if Bool
updated
                       then do
                      -- Key was present in the dictionary (stateVar) and
                      -- removed so we trace the removal.
                        let trs :: [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
trs = [ Transition :: forall state. state -> state -> Transition' state
Transition
                                     { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing)
                                     , toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown
                                     }
                                  ]
                        [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Transition'
    (MaybeUnknown
       (ConnectionState peerAddr handle handleError version m))]
 -> STM
      m
      [Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))])
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. (a -> b) -> a -> b
$
                          if Bool
shouldTrace
                             then Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition' Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
forall a. a -> [a] -> [a]
: [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
forall peerAddr handle handleError version (m :: * -> *).
[Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
trs
                             else [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
forall peerAddr handle handleError version (m :: * -> *).
[Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
trs
                      -- Key was not present in the dictionary (stateVar),
                      -- so we do not trace anything as it was already traced upon
                      -- deletion.
                      --
                      -- OR
                      --
                      -- Key was overwritten in the dictionary (stateVar),
                      -- so we do not trace anything as it was already traced upon
                      -- overwritting.
                       else [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a. Monad m => a -> m a
return [ ]

                  (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
trs
                  StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

    -- Pruning is done in two stages:
    -- * an STM transaction which selects which connections to prune, and sets
    --   their state to 'TerminatedState';
    -- * an io action which logs and cancells all the connection handler
    --   threads.
    mkPruneAction :: peerAddr
                  -> Int
                  -- ^ number of connections to prune
                  -> ConnectionManagerState peerAddr handle handleError version m
                  -> ConnectionState peerAddr handle handleError version  m
                  -- ^ next connection state, if it will not be pruned.
                  -> StrictTVar m (ConnectionState peerAddr handle handleError version m)
                  -> Async m ()
                  -> STM m (Bool, PruneAction m)
                  -- ^ return if the connection was choose to be prunned and the
                  -- 'PruneAction'
    mkPruneAction :: peerAddr
-> Int
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Async m ()
-> STM m (Bool, PruneAction m)
mkPruneAction peerAddr
peerAddr Int
numberToPrune ConnectionManagerState peerAddr handle handleError version m
state ConnectionState peerAddr handle handleError version m
connState' StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar Async m ()
connThread = do
      (choiceMap' :: Map peerAddr ( ConnectionType
                                  , Async m ()
                                  , StrictTVar m
                                      (ConnectionState
                                        peerAddr
                                        handle handleError
                                        version m)
                                  ))
        <- ((peerAddr
  -> MutableConnState peerAddr handle handleError version m
  -> STM
       m
       (Maybe
          (ConnectionType, Async m (),
           StrictTVar
             m (ConnectionState peerAddr handle handleError version m))))
 -> ConnectionManagerState peerAddr handle handleError version m
 -> STM
      m
      (Map
         peerAddr
         (ConnectionType, Async m (),
          StrictTVar
            m (ConnectionState peerAddr handle handleError version m))))
-> ConnectionManagerState peerAddr handle handleError version m
-> (peerAddr
    -> MutableConnState peerAddr handle handleError version m
    -> STM
         m
         (Maybe
            (ConnectionType, Async m (),
             StrictTVar
               m (ConnectionState peerAddr handle handleError version m))))
-> STM
     m
     (Map
        peerAddr
        (ConnectionType, Async m (),
         StrictTVar
           m (ConnectionState peerAddr handle handleError version m)))
forall a b c. (a -> b -> c) -> b -> a -> c
flip (peerAddr
 -> MutableConnState peerAddr handle handleError version m
 -> STM
      m
      (Maybe
         (ConnectionType, Async m (),
          StrictTVar
            m (ConnectionState peerAddr handle handleError version m))))
-> ConnectionManagerState peerAddr handle handleError version m
-> STM
     m
     (Map
        peerAddr
        (ConnectionType, Async m (),
         StrictTVar
           m (ConnectionState peerAddr handle handleError version m)))
forall (f :: * -> *) k a b.
Applicative f =>
(k -> a -> f (Maybe b)) -> Map k a -> f (Map k b)
Map.traverseMaybeWithKey ConnectionManagerState peerAddr handle handleError version m
state ((peerAddr
  -> MutableConnState peerAddr handle handleError version m
  -> STM
       m
       (Maybe
          (ConnectionType, Async m (),
           StrictTVar
             m (ConnectionState peerAddr handle handleError version m))))
 -> STM
      m
      (Map
         peerAddr
         (ConnectionType, Async m (),
          StrictTVar
            m (ConnectionState peerAddr handle handleError version m))))
-> (peerAddr
    -> MutableConnState peerAddr handle handleError version m
    -> STM
         m
         (Maybe
            (ConnectionType, Async m (),
             StrictTVar
               m (ConnectionState peerAddr handle handleError version m))))
-> STM
     m
     (Map
        peerAddr
        (ConnectionType, Async m (),
         StrictTVar
           m (ConnectionState peerAddr handle handleError version m)))
forall a b. (a -> b) -> a -> b
$ \peerAddr
_peerAddr MutableConnState { connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar = StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar' } ->
             (\ConnectionState peerAddr handle handleError version m
cs -> do
                 -- this expression returns @Maybe (connType, connThread)@;
                 -- 'traverseMaybeWithKey' collects all 'Just' cases.
                 Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (ConnectionState peerAddr handle handleError version m -> Bool
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m -> Bool
isInboundConn ConnectionState peerAddr handle handleError version m
cs)
                 (,,StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar') (ConnectionType
 -> Async m ()
 -> (ConnectionType, Async m (),
     StrictTVar
       m (ConnectionState peerAddr handle handleError version m)))
-> Maybe ConnectionType
-> Maybe
     (Async m ()
      -> (ConnectionType, Async m (),
          StrictTVar
            m (ConnectionState peerAddr handle handleError version m)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConnectionState peerAddr handle handleError version m
-> Maybe ConnectionType
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
-> Maybe ConnectionType
getConnType ConnectionState peerAddr handle handleError version m
cs
                              Maybe
  (Async m ()
   -> (ConnectionType, Async m (),
       StrictTVar
         m (ConnectionState peerAddr handle handleError version m)))
-> Maybe (Async m ())
-> Maybe
     (ConnectionType, Async m (),
      StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ConnectionState peerAddr handle handleError version m
-> Maybe (Async m ())
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
-> Maybe (Async m ())
getConnThread ConnectionState peerAddr handle handleError version m
cs)
         (ConnectionState peerAddr handle handleError version m
 -> Maybe
      (ConnectionType, Async m (),
       StrictTVar
         m (ConnectionState peerAddr handle handleError version m)))
-> STM m (ConnectionState peerAddr handle handleError version m)
-> STM
     m
     (Maybe
        (ConnectionType, Async m (),
         StrictTVar
           m (ConnectionState peerAddr handle handleError version m)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar'
      let choiceMap :: Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
choiceMap =
            case ConnectionState peerAddr handle handleError version m
-> Maybe ConnectionType
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
-> Maybe ConnectionType
getConnType ConnectionState peerAddr handle handleError version m
connState' of
              Maybe ConnectionType
Nothing -> Bool
-> Map
     peerAddr
     (ConnectionType, Async m (),
      StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
-> Map
     peerAddr
     (ConnectionType, Async m (),
      StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
forall a. HasCallStack => Bool -> a -> a
assert Bool
False Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
choiceMap'
              Just ConnectionType
a  -> peerAddr
-> (ConnectionType, Async m (),
    StrictTVar
      m (ConnectionState peerAddr handle handleError version m))
-> Map
     peerAddr
     (ConnectionType, Async m (),
      StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
-> Map
     peerAddr
     (ConnectionType, Async m (),
      StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert peerAddr
peerAddr (ConnectionType
a, Async m ()
connThread, StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar)
                                    Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
choiceMap'

      Set peerAddr
pruneSet <-
        PrunePolicy peerAddr (STM m)
cmPrunePolicy
          ((\(ConnectionType
a,Async m ()
_,StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
_) -> ConnectionType
a) ((ConnectionType, Async m (),
  StrictTVar
    m (ConnectionState peerAddr handle handleError version m))
 -> ConnectionType)
-> Map
     peerAddr
     (ConnectionType, Async m (),
      StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
-> Map peerAddr ConnectionType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
choiceMap)
          Int
numberToPrune

      let pruneMap :: Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
pruneMap = Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
choiceMap Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
-> Set peerAddr
-> Map
     peerAddr
     (ConnectionType, Async m (),
      StrictTVar
        m (ConnectionState peerAddr handle handleError version m))
forall k a. Ord k => Map k a -> Set k -> Map k a
`Map.restrictKeys` Set peerAddr
pruneSet
      Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
-> ((ConnectionType, Async m (),
     StrictTVar
       m (ConnectionState peerAddr handle handleError version m))
    -> STM m ())
-> STM m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
pruneMap (((ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
  -> STM m ())
 -> STM m ())
-> ((ConnectionType, Async m (),
     StrictTVar
       m (ConnectionState peerAddr handle handleError version m))
    -> STM m ())
-> STM m ()
forall a b. (a -> b) -> a -> b
$ \(ConnectionType
_, Async m ()
_, StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar') ->
        StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar' (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing)

      (Bool, PruneAction m) -> STM m (Bool, PruneAction m)
forall (m :: * -> *) a. Monad m => a -> m a
return ( peerAddr
peerAddr peerAddr -> Set peerAddr -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set peerAddr
pruneSet
             , m () -> PruneAction m
forall (m :: * -> *). m () -> PruneAction m
PruneAction (m () -> PruneAction m) -> m () -> PruneAction m
forall a b. (a -> b) -> a -> b
$ do
                 Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Set peerAddr
-> Int
-> Set peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Set peerAddr
-> Int
-> Set peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrPruneConnections (Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
-> Set peerAddr
forall k a. Map k a -> Set k
Map.keysSet Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
pruneMap)
                                                      Int
numberToPrune
                                                      (Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
-> Set peerAddr
forall k a. Map k a -> Set k
Map.keysSet Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
choiceMap))
                 -- we don't block until the thread terminates, delivering the
                 -- async exception is enough (although in this case, there's no
                 -- difference, since we put the connection in 'TerminatedState'
                 -- which avoids the 'cmTimeWaitTimeout').
                 Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
-> ((ConnectionType, Async m (),
     StrictTVar
       m (ConnectionState peerAddr handle handleError version m))
    -> m ())
-> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Map
  peerAddr
  (ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
pruneMap (((ConnectionType, Async m (),
   StrictTVar
     m (ConnectionState peerAddr handle handleError version m))
  -> m ())
 -> m ())
-> ((ConnectionType, Async m (),
     StrictTVar
       m (ConnectionState peerAddr handle handleError version m))
    -> m ())
-> m ()
forall a b. (a -> b) -> a -> b
$ \(ConnectionType
_, Async m ()
connThread', StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
_) ->
                                   ThreadId m -> AsyncCancelled -> m ()
forall (m :: * -> *) e.
(MonadFork m, Exception e) =>
ThreadId m -> e -> m ()
throwTo (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread')
                                           AsyncCancelled
AsyncCancelled
             )

    includeInboundConnectionImpl
        :: HasCallStack
        => FreshIdSupply m
        -> StrictTMVar m (ConnectionManagerState peerAddr handle handleError version m)
        -> ConnectionHandlerFn handlerTrace socket peerAddr handle handleError version m
        -> Word32
        -- ^ inbound connections hard limit
        -- TODO: This is needed because the accept loop can not guarantee that
        -- includeInboundConnection can run safely without going above the
        -- hardlimit.  We have to check if we are not above the hard limit
        -- after locking the connection manager state `TMVar` and  then decide
        -- whether we can include the connection or not.
        -> socket
        -- ^ resource to include in the state
        -> peerAddr
        -- ^ remote address used as an identifier of the resource
        -> m (Connected peerAddr handle handleError)
    includeInboundConnectionImpl :: FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> IncludeInboundConnection socket peerAddr handle handleError m
includeInboundConnectionImpl FreshIdSupply m
freshIdSupply
                                 StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                                 ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
handler
                                 Word32
hardLimit
                                 socket
socket
                                 peerAddr
peerAddr = do
        (Maybe
  (MutableConnState peerAddr handle handleError version m,
   Async m (), PromiseReader m (Either handleError (handle, version)))
r, ConnectionId peerAddr
connId) <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> m (ConnectionManagerState peerAddr handle handleError version m,
          (Maybe
             (MutableConnState peerAddr handle handleError version m,
              Async m (),
              PromiseReader m (Either handleError (handle, version))),
           ConnectionId peerAddr)))
-> m (Maybe
        (MutableConnState peerAddr handle handleError version m,
         Async m (),
         PromiseReader m (Either handleError (handle, version))),
      ConnectionId peerAddr)
forall (m :: * -> *) a b.
(MonadEvaluate m, MonadMask m, MonadSTM m) =>
StrictTMVar m a -> (a -> m (a, b)) -> m b
modifyTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar ((ConnectionManagerState peerAddr handle handleError version m
  -> m (ConnectionManagerState peerAddr handle handleError version m,
        (Maybe
           (MutableConnState peerAddr handle handleError version m,
            Async m (),
            PromiseReader m (Either handleError (handle, version))),
         ConnectionId peerAddr)))
 -> m (Maybe
         (MutableConnState peerAddr handle handleError version m,
          Async m (),
          PromiseReader m (Either handleError (handle, version))),
       ConnectionId peerAddr))
-> (ConnectionManagerState peerAddr handle handleError version m
    -> m (ConnectionManagerState peerAddr handle handleError version m,
          (Maybe
             (MutableConnState peerAddr handle handleError version m,
              Async m (),
              PromiseReader m (Either handleError (handle, version))),
           ConnectionId peerAddr)))
-> m (Maybe
        (MutableConnState peerAddr handle handleError version m,
         Async m (),
         PromiseReader m (Either handleError (handle, version))),
      ConnectionId peerAddr)
forall a b. (a -> b) -> a -> b
$ \ConnectionManagerState peerAddr handle handleError version m
state -> do
          peerAddr
localAddress <- Snocket m socket peerAddr -> socket -> m peerAddr
forall (m :: * -> *) fd addr. Snocket m fd addr -> fd -> m addr
getLocalAddr Snocket m socket peerAddr
cmSnocket socket
socket
          Int
numberOfCons <- STM m Int -> m Int
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m Int -> m Int) -> STM m Int -> m Int
forall a b. (a -> b) -> a -> b
$ ConnectionManagerState peerAddr handle handleError version m
-> STM m Int
countIncomingConnections ConnectionManagerState peerAddr handle handleError version m
state

          let connId :: ConnectionId peerAddr
connId = ConnectionId :: forall addr. addr -> addr -> ConnectionId addr
ConnectionId { peerAddr
localAddress :: peerAddr
localAddress :: peerAddr
localAddress, remoteAddress :: peerAddr
remoteAddress = peerAddr
peerAddr }

              -- Check if after accepting this connection we get above the
              -- hard limit
              canAccept :: Bool
canAccept = Int
numberOfCons Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
hardLimit

          if Bool
canAccept
          then do
            let provenance :: Provenance
provenance = Provenance
Inbound
            Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
TrIncludeConnection Provenance
provenance peerAddr
peerAddr)
            (PromiseReader m (Either handleError (handle, version))
reader, PromiseWriter m (Either handleError (handle, version))
writer) <- m (PromiseReader m (Either handleError (handle, version)),
   PromiseWriter m (Either handleError (handle, version)))
forall (m :: * -> *) a.
(MonadSTM m, MonadThrow (STM m)) =>
m (PromiseReader m a, PromiseWriter m a)
newEmptyPromiseIO
            (Async m ()
connThread, MutableConnState peerAddr handle handleError version m
connVar, Maybe (ConnectionState peerAddr handle handleError version m)
connState0, ConnectionState peerAddr handle handleError version m
connState) <-
              ((Async m (),
  MutableConnState peerAddr handle handleError version m,
  Maybe (ConnectionState peerAddr handle handleError version m),
  ConnectionState peerAddr handle handleError version m)
 -> m (Async m (),
       MutableConnState peerAddr handle handleError version m,
       Maybe (ConnectionState peerAddr handle handleError version m),
       ConnectionState peerAddr handle handleError version m))
-> m (Async m (),
      MutableConnState peerAddr handle handleError version m,
      Maybe (ConnectionState peerAddr handle handleError version m),
      ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix (((Async m (),
   MutableConnState peerAddr handle handleError version m,
   Maybe (ConnectionState peerAddr handle handleError version m),
   ConnectionState peerAddr handle handleError version m)
  -> m (Async m (),
        MutableConnState peerAddr handle handleError version m,
        Maybe (ConnectionState peerAddr handle handleError version m),
        ConnectionState peerAddr handle handleError version m))
 -> m (Async m (),
       MutableConnState peerAddr handle handleError version m,
       Maybe (ConnectionState peerAddr handle handleError version m),
       ConnectionState peerAddr handle handleError version m))
-> ((Async m (),
     MutableConnState peerAddr handle handleError version m,
     Maybe (ConnectionState peerAddr handle handleError version m),
     ConnectionState peerAddr handle handleError version m)
    -> m (Async m (),
          MutableConnState peerAddr handle handleError version m,
          Maybe (ConnectionState peerAddr handle handleError version m),
          ConnectionState peerAddr handle handleError version m))
-> m (Async m (),
      MutableConnState peerAddr handle handleError version m,
      Maybe (ConnectionState peerAddr handle handleError version m),
      ConnectionState peerAddr handle handleError version m)
forall a b. (a -> b) -> a -> b
$ \ ~(Async m ()
connThread, MutableConnState peerAddr handle handleError version m
_mutableConnVar, Maybe (ConnectionState peerAddr handle handleError version m)
_connState0, ConnectionState peerAddr handle handleError version m
_connState) -> do
                -- Either
                -- @
                --   Accepted    : ● → UnnegotiatedState Inbound
                --   Overwritten : ● → UnnegotiatedState Inbound
                -- @
                --
                -- This is subtle part, which needs to handle a near simultaneous
                -- open.  We cannot rely on 'ReservedOutboundState' state as
                -- a lock.  It may happen that the `requestOutboundConnection`
                -- will put 'ReservedOutboundState', but before it will call `connect`
                -- the `accept` call will return.  We overwrite the state and
                -- replace the connection state 'TVar' with a fresh one.  Nothing
                -- is blocked on the replaced 'TVar'.
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = Provenance
-> ConnectionId peerAddr
-> Async m ()
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Provenance
-> ConnectionId peerAddr
-> Async m ()
-> ConnectionState peerAddr handle handleError version m
UnnegotiatedState Provenance
provenance ConnectionId peerAddr
connId Async m ()
connThread
                (MutableConnState peerAddr handle handleError version m
mutableConnVar', Maybe (ConnectionState peerAddr handle handleError version m)
connState0') <-
                  STM
  m
  (MutableConnState peerAddr handle handleError version m,
   Maybe (ConnectionState peerAddr handle handleError version m))
-> m (MutableConnState peerAddr handle handleError version m,
      Maybe (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (MutableConnState peerAddr handle handleError version m,
    Maybe (ConnectionState peerAddr handle handleError version m))
 -> m (MutableConnState peerAddr handle handleError version m,
       Maybe (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (MutableConnState peerAddr handle handleError version m,
      Maybe (ConnectionState peerAddr handle handleError version m))
-> m (MutableConnState peerAddr handle handleError version m,
      Maybe (ConnectionState peerAddr handle handleError version m))
forall a b. (a -> b) -> a -> b
$ do
                    MutableConnState peerAddr handle handleError version m
v <- FreshIdSupply m
-> ConnectionState peerAddr handle handleError version m
-> STM m (MutableConnState peerAddr handle handleError version m)
forall (m :: * -> *) peerAddr handle handleError version.
MonadSTM m =>
FreshIdSupply m
-> ConnectionState peerAddr handle handleError version m
-> STM m (MutableConnState peerAddr handle handleError version m)
newMutableConnState FreshIdSupply m
freshIdSupply ConnectionState peerAddr handle handleError version m
connState'
                    StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> String -> STM m ()
forall (m :: * -> *) a.
MonadLabelledSTM m =>
StrictTVar m a -> String -> STM m ()
labelTVar (MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar MutableConnState peerAddr handle handleError version m
v) (String
"conn-state-" String -> ShowS
forall a. [a] -> [a] -> [a]
++ ConnectionId peerAddr -> String
forall a. Show a => a -> String
show ConnectionId peerAddr
connId)
                    Maybe (ConnectionState peerAddr handle handleError version m)
connState0' <- (MutableConnState peerAddr handle handleError version m
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> Maybe (MutableConnState peerAddr handle handleError version m)
-> STM
     m (Maybe (ConnectionState peerAddr handle handleError version m))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (StrictTVar
   m (ConnectionState peerAddr handle handleError version m)
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> (MutableConnState peerAddr handle handleError version m
    -> StrictTVar
         m (ConnectionState peerAddr handle handleError version m))
-> MutableConnState peerAddr handle handleError version m
-> STM m (ConnectionState peerAddr handle handleError version m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar)
                                            (peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state)
                    (MutableConnState peerAddr handle handleError version m,
 Maybe (ConnectionState peerAddr handle handleError version m))
-> STM
     m
     (MutableConnState peerAddr handle handleError version m,
      Maybe (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableConnState peerAddr handle handleError version m
v, Maybe (ConnectionState peerAddr handle handleError version m)
connState0')
                Async m ()
connThread' <-
                  StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> MutableConnState peerAddr handle handleError version m
-> socket
-> ConnectionId peerAddr
-> PromiseWriter m (Either handleError (handle, version))
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> m (Async m ())
forkConnectionHandler
                     StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar MutableConnState peerAddr handle handleError version m
mutableConnVar' socket
socket ConnectionId peerAddr
connId PromiseWriter m (Either handleError (handle, version))
writer ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
handler
                (Async m (),
 MutableConnState peerAddr handle handleError version m,
 Maybe (ConnectionState peerAddr handle handleError version m),
 ConnectionState peerAddr handle handleError version m)
-> m (Async m (),
      MutableConnState peerAddr handle handleError version m,
      Maybe (ConnectionState peerAddr handle handleError version m),
      ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. Monad m => a -> m a
return (Async m ()
connThread', MutableConnState peerAddr handle handleError version m
mutableConnVar', Maybe (ConnectionState peerAddr handle handleError version m)
connState0', ConnectionState peerAddr handle handleError version m
connState')

            Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr
                                 Transition :: forall state. state -> state -> Transition' state
Transition { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> (ConnectionState peerAddr handle handleError version m
    -> MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
-> Maybe (ConnectionState peerAddr handle handleError version m)
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known Maybe (ConnectionState peerAddr handle handleError version m)
connState0
                                            , toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState
                                            })
            (ConnectionManagerState peerAddr handle handleError version m,
 (Maybe
    (MutableConnState peerAddr handle handleError version m,
     Async m (),
     PromiseReader m (Either handleError (handle, version))),
  ConnectionId peerAddr))
-> m (ConnectionManagerState peerAddr handle handleError version m,
      (Maybe
         (MutableConnState peerAddr handle handleError version m,
          Async m (),
          PromiseReader m (Either handleError (handle, version))),
       ConnectionId peerAddr))
forall (m :: * -> *) a. Monad m => a -> m a
return ( peerAddr
-> MutableConnState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert peerAddr
peerAddr MutableConnState peerAddr handle handleError version m
connVar ConnectionManagerState peerAddr handle handleError version m
state
                   , ((MutableConnState peerAddr handle handleError version m,
 Async m (), PromiseReader m (Either handleError (handle, version)))
-> Maybe
     (MutableConnState peerAddr handle handleError version m,
      Async m (), PromiseReader m (Either handleError (handle, version)))
forall a. a -> Maybe a
Just (MutableConnState peerAddr handle handleError version m
connVar, Async m ()
connThread, PromiseReader m (Either handleError (handle, version))
reader), ConnectionId peerAddr
connId)
                   )
          else
            (ConnectionManagerState peerAddr handle handleError version m,
 (Maybe
    (MutableConnState peerAddr handle handleError version m,
     Async m (),
     PromiseReader m (Either handleError (handle, version))),
  ConnectionId peerAddr))
-> m (ConnectionManagerState peerAddr handle handleError version m,
      (Maybe
         (MutableConnState peerAddr handle handleError version m,
          Async m (),
          PromiseReader m (Either handleError (handle, version))),
       ConnectionId peerAddr))
forall (m :: * -> *) a. Monad m => a -> m a
return ( ConnectionManagerState peerAddr handle handleError version m
state
                   , (Maybe
  (MutableConnState peerAddr handle handleError version m,
   Async m (), PromiseReader m (Either handleError (handle, version)))
forall a. Maybe a
Nothing, ConnectionId peerAddr
connId)
                   )

        case Maybe
  (MutableConnState peerAddr handle handleError version m,
   Async m (), PromiseReader m (Either handleError (handle, version)))
r of
          Maybe
  (MutableConnState peerAddr handle handleError version m,
   Async m (), PromiseReader m (Either handleError (handle, version)))
Nothing ->
            Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
Disconnected ConnectionId peerAddr
connId Maybe handleError
forall a. Maybe a
Nothing)

          Just (mutableConnState :: MutableConnState peerAddr handle handleError version m
mutableConnState@MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar }
               , Async m ()
connThread, PromiseReader m (Either handleError (handle, version))
reader) -> do
            StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

            Either handleError (handle, version)
res <- STM m (Either handleError (handle, version))
-> m (Either handleError (handle, version))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m (Either handleError (handle, version))
 -> m (Either handleError (handle, version)))
-> STM m (Either handleError (handle, version))
-> m (Either handleError (handle, version))
forall a b. (a -> b) -> a -> b
$ PromiseReader m (Either handleError (handle, version))
-> STM m (Either handleError (handle, version))
forall (m :: * -> *) a. PromiseReader m a -> STM m a
readPromise PromiseReader m (Either handleError (handle, version))
reader
            case Either handleError (handle, version)
res of
              Left handleError
handleError -> do
                [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
transitions <- STM
  m
  [Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))]
-> m [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
 -> m [Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))])
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
-> m [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. (a -> b) -> a -> b
$ do
                  ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar

                  let connState' :: ConnectionState peerAddr handle handleError version m
connState' =
                        case handleError -> HandleErrorType
classifyHandleError handleError
handleError of
                          HandleErrorType
HandshakeFailure ->
                            ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatingState ConnectionId peerAddr
connId Async m ()
connThread
                                            (handleError -> Maybe handleError
forall a. a -> Maybe a
Just handleError
handleError)
                          HandleErrorType
HandshakeProtocolViolation ->
                            Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState (handleError -> Maybe handleError
forall a. a -> Maybe a
Just handleError
handleError)
                      transition :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition = ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'
                      absConnState :: AbstractState
absConnState = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
                      absConnState' :: AbstractState
absConnState' = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState')
                      shouldTrace :: Bool
shouldTrace = AbstractState
absConnState AbstractState -> AbstractState -> Bool
forall a. Eq a => a -> a -> Bool
/= AbstractState
TerminatedSt
                      isTerminating :: Bool
isTerminating = AbstractState
absConnState' AbstractState -> AbstractState -> Bool
forall a. Eq a => a -> a -> Bool
== AbstractState
TerminatingSt

                  Bool
updated <-
                    StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> STM
         m
         (ConnectionManagerState peerAddr handle handleError version m,
          Bool))
-> STM m Bool
forall (m :: * -> *) a b.
MonadSTM m =>
StrictTMVar m a -> (a -> STM m (a, b)) -> STM m b
modifyTMVarSTM
                      StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                      ( \ConnectionManagerState peerAddr handle handleError version m
state ->
                        case peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state of
                          Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> (ConnectionManagerState peerAddr handle handleError version m,
 Bool)
-> STM
     m
     (ConnectionManagerState peerAddr handle handleError version m,
      Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionManagerState peerAddr handle handleError version m
state, Bool
False)
                          Just MutableConnState peerAddr handle handleError version m
mutableConnState'  ->
                            if MutableConnState peerAddr handle handleError version m
mutableConnState' MutableConnState peerAddr handle handleError version m
-> MutableConnState peerAddr handle handleError version m -> Bool
forall a. Eq a => a -> a -> Bool
== MutableConnState peerAddr handle handleError version m
mutableConnState
                              then do
                                -- 'handleError' might be either a handshake
                                -- negotiation a protocol failure (an IO
                                -- exception, a timeout or codec failure).  In
                                -- the first case we should not reset the
                                -- connection as this is not a protocol error.
                                --
                                -- If we are deleting the connState from the
                                -- state then connState' can be TerminatingSt in
                                -- which case we are going to transition
                                -- TerminatingSt -> TerminatedSt. Otherwise,
                                -- Connection Manager cleanup will take care of
                                -- tracing accordingly.
                                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'

                                (ConnectionManagerState peerAddr handle handleError version m,
 Bool)
-> STM
     m
     (ConnectionManagerState peerAddr handle handleError version m,
      Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state , Bool
True)
                              else (ConnectionManagerState peerAddr handle handleError version m,
 Bool)
-> STM
     m
     (ConnectionManagerState peerAddr handle handleError version m,
      Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionManagerState peerAddr handle handleError version m
state                  , Bool
False)
                      )

                  let transitions :: [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
transitions =
                        [ Transition :: forall state. state -> state -> Transition' state
Transition
                            { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState'
                            , toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing)
                            }
                        | Bool
isTerminating
                        ] [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
forall a. [a] -> [a] -> [a]
++
                        [ Transition :: forall state. state -> state -> Transition' state
Transition
                            { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing)
                            , toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown
                            }
                        ]

                  if Bool
updated
                     then
                    -- Key was present in the dictionary (stateVar) and
                    -- removed so we trace the removal.
                      [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Transition'
    (MaybeUnknown
       (ConnectionState peerAddr handle handleError version m))]
 -> STM
      m
      [Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))])
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. (a -> b) -> a -> b
$
                        if Bool
shouldTrace
                           then Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
forall a. a -> [a] -> [a]
: [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
transitions
                           else [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
transitions
                    -- Key was not present in the dictionary (stateVar),
                    -- so we do not trace anything as it was already traced upon
                    -- deletion.
                    --
                    -- OR
                    --
                    -- Key was overwritten in the dictionary (stateVar),
                    -- so we do not trace anything as it was already traced upon
                    -- overwritting.
                     else [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a. Monad m => a -> m a
return [ ]

                (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
transitions
                StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

                Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
Disconnected ConnectionId peerAddr
connId (handleError -> Maybe handleError
forall a. a -> Maybe a
Just handleError
handleError))

              Right (handle
handle, version
version) -> do
                let dataFlow :: DataFlow
dataFlow = version -> DataFlow
connectionDataFlow version
version
                Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition <- STM
  m
  (Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))))
-> m (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
 -> m (Maybe
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
-> m (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ do
                  ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                  case ConnectionState peerAddr handle handleError version m
connState of
                    -- Inbound connections cannot be found in this state at this
                    -- stage.
                    ConnectionState peerAddr handle handleError version m
ReservedOutboundState ->
                      ConnectionManagerError peerAddr
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr -> CallStack -> ConnectionManagerError peerAddr
ImpossibleState peerAddr
peerAddr))

                    --
                    -- The common case.
                    --
                    -- Note: we don't set an explicit timeout here.  The
                    -- server will set a timeout and call
                    -- 'unregisterInboundConnection' when it expires.
                    --
                    UnnegotiatedState {} -> do
                      let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
InboundIdleState
                                         ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                                         (version -> DataFlow
connectionDataFlow version
version)
                      StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                      Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')

                    -- It is impossible to find a connection in 'OutboundUniState'
                    -- or 'OutboundDupState', since 'includeInboundConnection'
                    -- blocks until 'InboundState'.  This guarantees that this
                    -- transactions runs first in case of race between
                    -- 'requestOutboundConnection' and 'includeInboundConnection'.
                    OutboundUniState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle ->
                      ConnectionManagerError peerAddr
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr -> CallStack -> ConnectionManagerError peerAddr
ImpossibleState peerAddr
peerAddr))
                    OutboundDupState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle TimeoutExpired
_expired ->
                      ConnectionManagerError peerAddr
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr -> CallStack -> ConnectionManagerError peerAddr
ImpossibleState peerAddr
peerAddr))

                    OutboundIdleState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
dataFlow' -> do
                      let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
InboundIdleState
                                         ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                                         DataFlow
dataFlow'
                      StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                      Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')

                    InboundIdleState {} ->
                      ConnectionManagerError peerAddr
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr -> CallStack -> ConnectionManagerError peerAddr
ImpossibleState peerAddr
peerAddr))

                    -- At this stage the inbound connection cannot be in
                    -- 'InboundState', it would mean that there was another thread
                    -- that included that connection, but this would violate @TCP@
                    -- constraints.
                    InboundState {} ->
                      ConnectionManagerError peerAddr
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr -> CallStack -> ConnectionManagerError peerAddr
ImpossibleState peerAddr
peerAddr))

                    DuplexState {} ->
                      ConnectionManagerError peerAddr
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr -> CallStack -> ConnectionManagerError peerAddr
ImpossibleState peerAddr
peerAddr))

                    TerminatingState {} -> Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing

                    TerminatedState {} -> Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing

                (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition
                StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

                -- Note that we don't set a timeout thread here which would
                -- perform:
                -- @
                --   Commit^{dataFlow}
                --     : InboundIdleState dataFlow
                --     → TerminatingState
                -- @
                -- This is not needed!  When we return from this call, the inbound
                -- protocol governor will monitor the connection.  Once it becomes
                -- idle, it will call 'unregisterInboundConnection' which will
                -- perform the aforementioned @Commit@ transition.

                -- If mbTransition is Nothing, it means that the connVar was read
                -- either in Terminating or TerminatedState. Either case we should
                -- return Disconnected instead of Connected.
                case Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition of
                  Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
Nothing -> Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return (Connected peerAddr handle handleError
 -> m (Connected peerAddr handle handleError))
-> Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall a b. (a -> b) -> a -> b
$ ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
Disconnected ConnectionId peerAddr
connId Maybe handleError
forall a. Maybe a
Nothing
                  Just {} -> do
                    case InResponderMode
  muxMode (ControlChannel m (NewConnection peerAddr handle))
inboundGovernorControlChannel of
                      InResponderMode ControlChannel m (NewConnection peerAddr handle)
controlChannel ->
                        STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ ControlChannel m (NewConnection peerAddr handle)
-> ConnectionId peerAddr -> DataFlow -> handle -> STM m ()
forall (m :: * -> *) peerAddr handle.
ControlChannel m (NewConnection peerAddr handle)
-> ConnectionId peerAddr -> DataFlow -> handle -> STM m ()
ControlChannel.newInboundConnection
                                       ControlChannel m (NewConnection peerAddr handle)
controlChannel ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle
                      InResponderMode
  muxMode (ControlChannel m (NewConnection peerAddr handle))
NotInResponderMode -> () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return (Connected peerAddr handle handleError
 -> m (Connected peerAddr handle handleError))
-> Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall a b. (a -> b) -> a -> b
$ ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
Connected ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle

    -- Needs 'mask' in order to guarantee that the traces are logged if the an
    -- Async exception lands between the successful STM action and the logging action.
    unregisterInboundConnectionImpl
        :: StrictTMVar m (ConnectionManagerState peerAddr handle handleError version m)
        -> peerAddr
        -> m (OperationResult DemotedToColdRemoteTr)
    unregisterInboundConnectionImpl :: StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult DemotedToColdRemoteTr)
unregisterInboundConnectionImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar peerAddr
peerAddr = m (OperationResult DemotedToColdRemoteTr)
-> m (OperationResult DemotedToColdRemoteTr)
forall (m :: * -> *) a. MonadMask m => m a -> m a
mask_ (m (OperationResult DemotedToColdRemoteTr)
 -> m (OperationResult DemotedToColdRemoteTr))
-> m (OperationResult DemotedToColdRemoteTr)
-> m (OperationResult DemotedToColdRemoteTr)
forall a b. (a -> b) -> a -> b
$ do
      Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
TrUnregisterConnection Provenance
Inbound peerAddr
peerAddr)
      (Maybe (Async m ())
mbThread, Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition, OperationResult DemotedToColdRemoteTr
result, Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion) <- STM
  m
  (Maybe (Async m ()),
   Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))),
   OperationResult DemotedToColdRemoteTr,
   Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Maybe (Async m ()),
    Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))),
    OperationResult DemotedToColdRemoteTr,
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> m (Maybe (Async m ()),
       Maybe
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))),
       OperationResult DemotedToColdRemoteTr,
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$ do
        ConnectionManagerState peerAddr handle handleError version m
state <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
        case peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state of
          Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> do
            -- Note: this can happen if the inbound connection manager is
            -- notified late about the connection which has already terminated
            -- at this point.
            (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (f :: * -> *) a. Applicative f => a -> f a
pure ( Maybe (Async m ())
forall a. Maybe a
Nothing
                 , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                 , DemotedToColdRemoteTr -> OperationResult DemotedToColdRemoteTr
forall a. a -> OperationResult a
OperationSuccess DemotedToColdRemoteTr
CommitTr
                 , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                 )
          Just MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar } -> do
            ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
            let st :: AbstractState
st = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
            case ConnectionState peerAddr handle handleError version m
connState of
              -- In any of the following two states unregistering is not
              -- supported.  'includeInboundConnection' is a synchronous
              -- operation which returns only once the connection is
              -- negotiated.
              ConnectionState peerAddr handle handleError version m
ReservedOutboundState ->
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                       , AbstractState -> OperationResult DemotedToColdRemoteTr
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              UnnegotiatedState Provenance
_ ConnectionId peerAddr
_ Async m ()
_ ->
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                       , AbstractState -> OperationResult DemotedToColdRemoteTr
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              -- @
              --   TimeoutExpired : OutboundState^\tau Duplex
              --                  → OutboundState      Duplex
              -- @
              OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Ticking -> do
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Expired
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , DemotedToColdRemoteTr -> OperationResult DemotedToColdRemoteTr
forall a. a -> OperationResult a
OperationSuccess DemotedToColdRemoteTr
KeepTr
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              OutboundDupState ConnectionId peerAddr
connId Async m ()
_connThread handle
_handle TimeoutExpired
Expired ->
                Bool
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a. HasCallStack => Bool -> a -> a
assert Bool
False (STM
   m
   (Maybe (Async m ()),
    Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))),
    OperationResult DemotedToColdRemoteTr,
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> STM
      m
      (Maybe (Async m ()),
       Maybe
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))),
       OperationResult DemotedToColdRemoteTr,
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                       , DemotedToColdRemoteTr -> OperationResult DemotedToColdRemoteTr
forall a. a -> OperationResult a
OperationSuccess DemotedToColdRemoteTr
KeepTr
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                 (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
UnregisterInboundConnection (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                                              AbstractState
st)
                                 )
                       )

              OutboundUniState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle ->
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                       , AbstractState -> OperationResult DemotedToColdRemoteTr
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              -- unexpected state, this state is reachable only from outbound
              -- states
              OutboundIdleState ConnectionId peerAddr
connId Async m ()
_connThread handle
_handle DataFlow
_dataFlow ->
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                       , DemotedToColdRemoteTr -> OperationResult DemotedToColdRemoteTr
forall a. a -> OperationResult a
OperationSuccess DemotedToColdRemoteTr
CommitTr
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                 (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
UnregisterInboundConnection (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                                              AbstractState
st)
                                 )
                       )

              -- @
              --   Commit^{dataFlow} : InboundIdleState dataFlow
              --                     → TerminatingState
              -- @
              --
              -- Note: the 'TrDemotedToColdRemote' is logged by the server.
              InboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
_handle DataFlow
_dataFlow -> do
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatingState ConnectionId peerAddr
connId Async m ()
connThread Maybe handleError
forall a. Maybe a
Nothing
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
                       , Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , DemotedToColdRemoteTr -> OperationResult DemotedToColdRemoteTr
forall a. a -> OperationResult a
OperationSuccess DemotedToColdRemoteTr
CommitTr
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              -- the inbound protocol governor was supposed to call
              -- 'demotedToColdRemote' first.
              InboundState ConnectionId peerAddr
connId Async m ()
connThread handle
_handle DataFlow
_dataFlow -> do
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatingState ConnectionId peerAddr
connId Async m ()
connThread Maybe handleError
forall a. Maybe a
Nothing
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Async m () -> Maybe (Async m ())
forall a. a -> Maybe a
Just Async m ()
connThread
                       , Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , AbstractState -> OperationResult DemotedToColdRemoteTr
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                 (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
UnregisterInboundConnection (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                                              AbstractState
st)
                                 )
                       )

              -- the inbound connection governor ought to call
              -- 'demotedToColdRemote' first.
              DuplexState ConnectionId peerAddr
connId Async m ()
connThread handle
handle -> do
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Ticking
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , AbstractState -> OperationResult DemotedToColdRemoteTr
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                 (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
UnregisterInboundConnection (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                                              AbstractState
st)
                                 )
                       )

              -- If 'unregisterOutboundConnection' is called just before
              -- 'unregisterInboundConnection', the latter one might observe
              -- 'TerminatingState'.
              TerminatingState ConnectionId peerAddr
_connId Async m ()
_connThread Maybe handleError
_handleError ->
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                       , DemotedToColdRemoteTr -> OperationResult DemotedToColdRemoteTr
forall a. a -> OperationResult a
OperationSuccess DemotedToColdRemoteTr
CommitTr
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              -- However, 'TerminatedState' should not be observable by
              -- 'unregisterInboundConnection', unless 'cmTimeWaitTimeout' is
              -- close to 'serverProtocolIdleTimeout'.
              TerminatedState Maybe handleError
_handleError ->
                (Maybe (Async m ()),
 Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 OperationResult DemotedToColdRemoteTr,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe (Async m ()),
      Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      OperationResult DemotedToColdRemoteTr,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe (Async m ())
forall a. Maybe a
Nothing
                       , Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                       , AbstractState -> OperationResult DemotedToColdRemoteTr
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
TerminatedSt
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

      (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition
      StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

      -- 'throwTo' avoids blocking until 'cmTimeWaitTimeout' expires.
      (Async m () -> m ()) -> Maybe (Async m ()) -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((ThreadId m -> AsyncCancelled -> m ())
-> AsyncCancelled -> ThreadId m -> m ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip ThreadId m -> AsyncCancelled -> m ()
forall (m :: * -> *) e.
(MonadFork m, Exception e) =>
ThreadId m -> e -> m ()
throwTo AsyncCancelled
AsyncCancelled (ThreadId m -> m ())
-> (Async m () -> ThreadId m) -> Async m () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId)
                Maybe (Async m ())
mbThread

      Maybe (ConnectionManagerTrace peerAddr handlerTrace)
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall (m :: * -> *) a.
Applicative m =>
Maybe a -> (a -> m ()) -> m ()
whenJust Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion ((ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ())
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \ConnectionManagerTrace peerAddr handlerTrace
tr -> do
        Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer ConnectionManagerTrace peerAddr handlerTrace
tr
        Any -> Any
_ <- (Any -> Any) -> m (Any -> Any)
forall (m :: * -> *) a. MonadEvaluate m => a -> m a
evaluate (Bool -> Any -> Any
forall a. HasCallStack => Bool -> a -> a
assert Bool
False)
        () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

      OperationResult DemotedToColdRemoteTr
-> m (OperationResult DemotedToColdRemoteTr)
forall (m :: * -> *) a. Monad m => a -> m a
return OperationResult DemotedToColdRemoteTr
result

    requestOutboundConnectionImpl
        :: HasCallStack
        => FreshIdSupply m
        -> StrictTMVar m (ConnectionManagerState peerAddr handle handleError version m)
        -> ConnectionHandlerFn handlerTrace socket peerAddr handle handleError version m
        -> peerAddr
        -> m (Connected peerAddr handle handleError)
    requestOutboundConnectionImpl :: FreshIdSupply m
-> StrictTMVar
     m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> RequestOutboundConnection peerAddr handle handleError m
requestOutboundConnectionImpl FreshIdSupply m
freshIdSupply StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
handler peerAddr
peerAddr = do
        let provenance :: Provenance
provenance = Provenance
Outbound
        Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
TrIncludeConnection Provenance
provenance peerAddr
peerAddr)
        (Maybe
  (Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace))
trace, mutableConnState :: MutableConnState peerAddr handle handleError version m
mutableConnState@MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar }
              , Either
  (ConnectionManagerError peerAddr)
  (Wedge
     (Connected peerAddr handle handleError) (ConnectionId peerAddr))
eHandleWedge) <- STM
  m
  (Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace)),
   MutableConnState peerAddr handle handleError version m,
   Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> m (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Maybe
      (Either
         (TransitionTrace
            peerAddr (ConnectionState peerAddr handle handleError version m))
         (ConnectionManagerTrace peerAddr handlerTrace)),
    MutableConnState peerAddr handle handleError version m,
    Either
      (ConnectionManagerError peerAddr)
      (Wedge
         (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
 -> m (Maybe
         (Either
            (TransitionTrace
               peerAddr (ConnectionState peerAddr handle handleError version m))
            (ConnectionManagerTrace peerAddr handlerTrace)),
       MutableConnState peerAddr handle handleError version m,
       Either
         (ConnectionManagerError peerAddr)
         (Wedge
            (Connected peerAddr handle handleError) (ConnectionId peerAddr))))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> m (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall a b. (a -> b) -> a -> b
$ do
          ConnectionManagerState peerAddr handle handleError version m
state <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
          case peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state of
            Just mutableConnState :: MutableConnState peerAddr handle handleError version m
mutableConnState@MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar } -> do
              ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
              let st :: AbstractState
st = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
              case ConnectionState peerAddr handle handleError version m
connState of
                ConnectionState peerAddr handle handleError version m
ReservedOutboundState ->
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionExists Provenance
provenance peerAddr
peerAddr AbstractState
st))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack
                                  (Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance peerAddr
peerAddr))
                         )

                UnnegotiatedState Provenance
Outbound ConnectionId peerAddr
_connId Async m ()
_connThread -> do
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionExists Provenance
provenance peerAddr
peerAddr AbstractState
st))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack
                                  (Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance peerAddr
peerAddr))
                         )

                UnnegotiatedState Provenance
Inbound ConnectionId peerAddr
connId Async m ()
_connThread ->
                  -- we must not block inside @modifyTVar stateVar@, we
                  -- return 'There' to indicate that we need to block on
                  -- the connection state.
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe
  (Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace))
forall a. Maybe a
Nothing
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , Wedge
  (Connected peerAddr handle handleError) (ConnectionId peerAddr)
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. b -> Either a b
Right (ConnectionId peerAddr
-> Wedge
     (Connected peerAddr handle handleError) (ConnectionId peerAddr)
forall a b. b -> Wedge a b
There ConnectionId peerAddr
connId)
                         )

                OutboundUniState {} -> do
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionExists Provenance
provenance peerAddr
peerAddr AbstractState
st))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack
                                  (Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance peerAddr
peerAddr))
                         )

                OutboundDupState {} -> do
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionExists Provenance
provenance peerAddr
peerAddr AbstractState
st))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack
                                  (Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance peerAddr
peerAddr))
                         )

                OutboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
_dataFlow ->
                  let tr :: AbstractState
tr = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState) in
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
TrForbiddenOperation peerAddr
peerAddr AbstractState
tr))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr
-> AbstractState -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr
-> AbstractState -> CallStack -> ConnectionManagerError peerAddr
ForbiddenOperation peerAddr
peerAddr AbstractState
tr))
                         )

                InboundIdleState ConnectionId peerAddr
connId Async m ()
_connThread handle
_handle DataFlow
Unidirectional -> do
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrForbiddenConnection ConnectionId peerAddr
connId))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack
                                  (ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
ForbiddenConnection ConnectionId peerAddr
connId))
                         )

                InboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
handle dataFlow :: DataFlow
dataFlow@DataFlow
Duplex -> do
                  -- @
                  --   Awake^{Duplex}_{Local} : InboundIdleState Duplex
                  --                          → OutboundState^\tau Duplex
                  -- @
                  let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Ticking
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. a -> Either a b
Left (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace
                                         peerAddr
peerAddr
                                         (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , Wedge
  (Connected peerAddr handle handleError) (ConnectionId peerAddr)
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. b -> Either a b
Right (Connected peerAddr handle handleError
-> Wedge
     (Connected peerAddr handle handleError) (ConnectionId peerAddr)
forall a b. a -> Wedge a b
Here (ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
Connected ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle))
                         )

                InboundState ConnectionId peerAddr
connId Async m ()
_connThread handle
_handle DataFlow
Unidirectional -> do
                  -- the remote side negotiated unidirectional connection, we
                  -- cannot re-use it.
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrForbiddenConnection ConnectionId peerAddr
connId))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack
                                  (ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
ForbiddenConnection ConnectionId peerAddr
connId))
                         )

                InboundState ConnectionId peerAddr
connId Async m ()
connThread handle
handle dataFlow :: DataFlow
dataFlow@DataFlow
Duplex -> do
                  -- @
                  --   PromotedToWarm^{Duplex}_{Local} : InboundState Duplex
                  --                                   → DuplexState
                  -- @
                  let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
DuplexState ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. a -> Either a b
Left (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace
                                        peerAddr
peerAddr
                                        (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , Wedge
  (Connected peerAddr handle handleError) (ConnectionId peerAddr)
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. b -> Either a b
Right (Connected peerAddr handle handleError
-> Wedge
     (Connected peerAddr handle handleError) (ConnectionId peerAddr)
forall a b. a -> Wedge a b
Here (ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
Connected ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle))
                         )

                DuplexState ConnectionId peerAddr
_connId Async m ()
_connThread  handle
_handle ->
                  (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr
-> AbstractState
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionExists Provenance
provenance peerAddr
peerAddr AbstractState
st))
                         , MutableConnState peerAddr handle handleError version m
mutableConnState
                         , ConnectionManagerError peerAddr
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. a -> Either a b
Left ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack
                                  (Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance peerAddr
peerAddr))
                         )

                TerminatingState ConnectionId peerAddr
_connId Async m ()
_connThread Maybe handleError
_handleError ->
                  -- await for 'TerminatedState' or for removal of the
                  -- connection from the state.
                  STM
  m
  (Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace)),
   MutableConnState peerAddr handle handleError version m,
   Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. MonadSTM m => STM m a
retry

                TerminatedState Maybe handleError
_handleError -> do
                  -- the connection terminated; we can not reset 'connVar' and
                  -- start afresh. We should wait for the removal of the
                  -- connection from the state.
                  STM
  m
  (Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace)),
   MutableConnState peerAddr handle handleError version m,
   Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. MonadSTM m => STM m a
retry

            Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> do
              let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
ReservedOutboundState
              (MutableConnState peerAddr handle handleError version m
mutableConnState :: MutableConnState peerAddr handle handleError
                                                    version m)
                <- FreshIdSupply m
-> ConnectionState peerAddr handle handleError version m
-> STM m (MutableConnState peerAddr handle handleError version m)
forall (m :: * -> *) peerAddr handle handleError version.
MonadSTM m =>
FreshIdSupply m
-> ConnectionState peerAddr handle handleError version m
-> STM m (MutableConnState peerAddr handle handleError version m)
newMutableConnState FreshIdSupply m
freshIdSupply ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
              -- TODO: label `connVar` using 'ConnectionId'
              StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> String -> STM m ()
forall (m :: * -> *) a.
MonadLabelledSTM m =>
StrictTVar m a -> String -> STM m ()
labelTVar (MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar MutableConnState peerAddr handle handleError version m
mutableConnState) (String
"conn-state-" String -> ShowS
forall a. [a] -> [a] -> [a]
++ peerAddr -> String
forall a. Show a => a -> String
show peerAddr
peerAddr)

              -- record the @connVar@ in 'ConnectionManagerState' we can use
              -- 'swapTMVar' as we did not use 'takeTMVar' at the beginning of
              -- this transaction.  Since we already 'readTMVar', it will not
              -- block.
              (Maybe (ConnectionState peerAddr handle handleError version m)
mbConnState
                 :: Maybe (ConnectionState peerAddr handle handleError version m))
                   <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> ConnectionManagerState peerAddr handle handleError version m
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a.
MonadSTM m =>
StrictTMVar m a -> a -> STM m a
swapTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                        (peerAddr
-> MutableConnState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert peerAddr
peerAddr MutableConnState peerAddr handle handleError version m
mutableConnState ConnectionManagerState peerAddr handle handleError version m
state)
                        STM
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> STM
         m (Maybe (ConnectionState peerAddr handle handleError version m)))
-> STM
     m (Maybe (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (MutableConnState peerAddr handle handleError version m
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> Maybe (MutableConnState peerAddr handle handleError version m)
-> STM
     m (Maybe (ConnectionState peerAddr handle handleError version m))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar (StrictTVar
   m (ConnectionState peerAddr handle handleError version m)
 -> STM m (ConnectionState peerAddr handle handleError version m))
-> (MutableConnState peerAddr handle handleError version m
    -> StrictTVar
         m (ConnectionState peerAddr handle handleError version m))
-> MutableConnState peerAddr handle handleError version m
-> STM m (ConnectionState peerAddr handle handleError version m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar) (Maybe (MutableConnState peerAddr handle handleError version m)
 -> STM
      m (Maybe (ConnectionState peerAddr handle handleError version m)))
-> (ConnectionManagerState peerAddr handle handleError version m
    -> Maybe (MutableConnState peerAddr handle handleError version m))
-> ConnectionManagerState peerAddr handle handleError version m
-> STM
     m (Maybe (ConnectionState peerAddr handle handleError version m))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr
              (Maybe
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace)),
 MutableConnState peerAddr handle handleError version m,
 Either
   (ConnectionManagerError peerAddr)
   (Wedge
      (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
-> STM
     m
     (Maybe
        (Either
           (TransitionTrace
              peerAddr (ConnectionState peerAddr handle handleError version m))
           (ConnectionManagerTrace peerAddr handlerTrace)),
      MutableConnState peerAddr handle handleError version m,
      Either
        (ConnectionManagerError peerAddr)
        (Wedge
           (Connected peerAddr handle handleError) (ConnectionId peerAddr)))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
forall a. a -> Maybe a
Just (TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. a -> Either a b
Left (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace
                                    peerAddr
peerAddr
                                    Transition :: forall state. state -> state -> Transition' state
Transition {
                                        fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> (ConnectionState peerAddr handle handleError version m
    -> MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
-> Maybe (ConnectionState peerAddr handle handleError version m)
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known Maybe (ConnectionState peerAddr handle handleError version m)
mbConnState,
                                        toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                                      }))
                     , MutableConnState peerAddr handle handleError version m
mutableConnState
                     , Wedge
  (Connected peerAddr handle handleError) (ConnectionId peerAddr)
-> Either
     (ConnectionManagerError peerAddr)
     (Wedge
        (Connected peerAddr handle handleError) (ConnectionId peerAddr))
forall a b. b -> Either a b
Right Wedge
  (Connected peerAddr handle handleError) (ConnectionId peerAddr)
forall a b. Wedge a b
Nowhere
                     )

        (Either
   (TransitionTrace
      peerAddr (ConnectionState peerAddr handle handleError version m))
   (ConnectionManagerTrace peerAddr handlerTrace)
 -> m ())
-> Maybe
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ ((TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ())
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
-> m ()
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer) (Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer)) Maybe
  (Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace))
trace
        StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
        case Either
  (ConnectionManagerError peerAddr)
  (Wedge
     (Connected peerAddr handle handleError) (ConnectionId peerAddr))
eHandleWedge of
          Left ConnectionManagerError peerAddr
e ->
            ConnectionManagerError peerAddr
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO ConnectionManagerError peerAddr
e

          -- connection manager does not have a connection with @peerAddr@.
          Right Wedge
  (Connected peerAddr handle handleError) (ConnectionId peerAddr)
Nowhere -> do
            (PromiseReader m (Either handleError (handle, version))
reader, PromiseWriter m (Either handleError (handle, version))
writer) <- m (PromiseReader m (Either handleError (handle, version)),
   PromiseWriter m (Either handleError (handle, version)))
forall (m :: * -> *) a.
(MonadSTM m, MonadThrow (STM m)) =>
m (PromiseReader m a, PromiseWriter m a)
newEmptyPromiseIO

            (ConnectionId peerAddr
connId, Async m ()
connThread) <-
              -- This section of code passes the control over socket from
              -- `bracketOnError` which is responsible for:
              --
              --    * creating socket
              --    * connecting to remote host
              --    * obtaining local address of the connection
              --
              -- to the connection handler and its resource cleanup.
              -- Both the 'bracketOnError''s resource handler and the
              -- connection handler cleanup function are responsible for:
              --
              --  * closing the socket
              --  * freeing the slot in connection manager state map
              --
              ((forall a. m a -> m a) -> m (ConnectionId peerAddr, Async m ()))
-> m (ConnectionId peerAddr, Async m ())
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m (ConnectionId peerAddr, Async m ()))
 -> m (ConnectionId peerAddr, Async m ()))
-> ((forall a. m a -> m a)
    -> m (ConnectionId peerAddr, Async m ()))
-> m (ConnectionId peerAddr, Async m ())
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
unmask -> do

                --
                -- connect
                --

                (socket
socket, ConnectionId peerAddr
connId) <-
                  m (socket, ConnectionId peerAddr)
-> m (socket, ConnectionId peerAddr)
forall a. m a -> m a
unmask (m (socket, ConnectionId peerAddr)
 -> m (socket, ConnectionId peerAddr))
-> m (socket, ConnectionId peerAddr)
-> m (socket, ConnectionId peerAddr)
forall a b. (a -> b) -> a -> b
$ m socket
-> (socket -> m ())
-> (socket -> m (socket, ConnectionId peerAddr))
-> m (socket, ConnectionId peerAddr)
forall (m :: * -> *) a b c.
MonadCatch m =>
m a -> (a -> m b) -> (a -> m c) -> m c
bracketOnError
                    (Snocket m socket peerAddr -> peerAddr -> m socket
forall (m :: * -> *) fd addr. Snocket m fd addr -> addr -> m fd
openToConnect Snocket m socket peerAddr
cmSnocket peerAddr
peerAddr)
                    (\socket
socket -> m () -> m ()
forall (m :: * -> *) a. MonadMask m => m a -> m a
uninterruptibleMask_ (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
                      Snocket m socket peerAddr -> socket -> m ()
forall (m :: * -> *) fd addr. Snocket m fd addr -> fd -> m ()
close Snocket m socket peerAddr
cmSnocket socket
socket
                      Either
  ()
  [Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))]
res <- STM
  m
  (Either
     ()
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))])
-> m (Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Either
      ()
      [Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))])
 -> m (Either
         ()
         [Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))]))
-> STM
     m
     (Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
-> m (Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
forall a b. (a -> b) -> a -> b
$ StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> STM
         m
         (ConnectionManagerState peerAddr handle handleError version m,
          Either
            ()
            [Transition'
               (MaybeUnknown
                  (ConnectionState peerAddr handle handleError version m))]))
-> STM
     m
     (Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
forall (m :: * -> *) a b.
MonadSTM m =>
StrictTMVar m a -> (a -> STM m (a, b)) -> STM m b
modifyTMVarSTM StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar ((ConnectionManagerState peerAddr handle handleError version m
  -> STM
       m
       (ConnectionManagerState peerAddr handle handleError version m,
        Either
          ()
          [Transition'
             (MaybeUnknown
                (ConnectionState peerAddr handle handleError version m))]))
 -> STM
      m
      (Either
         ()
         [Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))]))
-> (ConnectionManagerState peerAddr handle handleError version m
    -> STM
         m
         (ConnectionManagerState peerAddr handle handleError version m,
          Either
            ()
            [Transition'
               (MaybeUnknown
                  (ConnectionState peerAddr handle handleError version m))]))
-> STM
     m
     (Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
forall a b. (a -> b) -> a -> b
$ \ConnectionManagerState peerAddr handle handleError version m
state -> do
                        case peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state of
                          -- Lookup failed, which means connection was already
                          -- removed.  So we just update the connVar and trace
                          -- accordingly.
                          Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> do
                            ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                            let connState' :: ConnectionState peerAddr handle handleError version m
connState' = Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing
                            StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                            (ConnectionManagerState peerAddr handle handleError version m,
 Either
   ()
   [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))])
-> STM
     m
     (ConnectionManagerState peerAddr handle handleError version m,
      Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
forall (m :: * -> *) a. Monad m => a -> m a
return
                              ( ConnectionManagerState peerAddr handle handleError version m
state
                              , [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> Either
     ()
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. b -> Either a b
Right [ ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                                      , MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition' state
Transition (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState') MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown
                                      ]
                              )

                          -- Current connVar.
                          Just MutableConnState peerAddr handle handleError version m
mutableConnState' ->
                            -- If accept call returned first than connect then
                            -- the connVar will be replaced. If it was
                            -- replaced then we do not need to do anything.
                            -- Otherwise, we need to remove the connVar from
                            -- the state and trace accordingly.
                            if MutableConnState peerAddr handle handleError version m
mutableConnState' MutableConnState peerAddr handle handleError version m
-> MutableConnState peerAddr handle handleError version m -> Bool
forall a. Eq a => a -> a -> Bool
== MutableConnState peerAddr handle handleError version m
mutableConnState
                               then do
                                ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                                let state' :: ConnectionManagerState peerAddr handle handleError version m
state' = peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state
                                    connState' :: ConnectionState peerAddr handle handleError version m
connState' = Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing
                                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                                (ConnectionManagerState peerAddr handle handleError version m,
 Either
   ()
   [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))])
-> STM
     m
     (ConnectionManagerState peerAddr handle handleError version m,
      Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
forall (m :: * -> *) a. Monad m => a -> m a
return
                                  ( ConnectionManagerState peerAddr handle handleError version m
state'
                                  , [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> Either
     ()
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. b -> Either a b
Right [ ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState'
                                          , MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition' state
Transition (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m
connState')
                                                       MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown
                                          ]
                                  )
                               else
                                (ConnectionManagerState peerAddr handle handleError version m,
 Either
   ()
   [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))])
-> STM
     m
     (ConnectionManagerState peerAddr handle handleError version m,
      Either
        ()
        [Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))])
forall (m :: * -> *) a. Monad m => a -> m a
return
                                  ( ConnectionManagerState peerAddr handle handleError version m
state
                                  , ()
-> Either
     ()
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. a -> Either a b
Left ()
                                  )

                      case Either
  ()
  [Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))]
res of
                        Left ()
_ -> () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
                        Right [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
trs ->
                          (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
trs
                      StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                    )
                    ((socket -> m (socket, ConnectionId peerAddr))
 -> m (socket, ConnectionId peerAddr))
-> (socket -> m (socket, ConnectionId peerAddr))
-> m (socket, ConnectionId peerAddr)
forall a b. (a -> b) -> a -> b
$ \socket
socket -> do
                      Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
TrConnectionNotFound Provenance
provenance peerAddr
peerAddr)
                      Maybe peerAddr
addr <-
                        case peerAddr -> Maybe AddressType
cmAddressType peerAddr
peerAddr of
                          Maybe AddressType
Nothing -> Maybe peerAddr -> m (Maybe peerAddr)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe peerAddr
forall a. Maybe a
Nothing
                          Just AddressType
IPv4Address ->
                               (peerAddr -> m ()) -> Maybe peerAddr -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Snocket m socket peerAddr -> socket -> peerAddr -> m ()
forall (m :: * -> *) fd addr.
Snocket m fd addr -> fd -> addr -> m ()
bind Snocket m socket peerAddr
cmSnocket socket
socket)
                                         Maybe peerAddr
cmIPv4Address
                            m () -> Maybe peerAddr -> m (Maybe peerAddr)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe peerAddr
cmIPv4Address
                          Just AddressType
IPv6Address ->
                               (peerAddr -> m ()) -> Maybe peerAddr -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Snocket m socket peerAddr -> socket -> peerAddr -> m ()
forall (m :: * -> *) fd addr.
Snocket m fd addr -> fd -> addr -> m ()
bind Snocket m socket peerAddr
cmSnocket socket
socket)
                                         Maybe peerAddr
cmIPv6Address
                            m () -> Maybe peerAddr -> m (Maybe peerAddr)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe peerAddr
cmIPv6Address

                      Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Maybe peerAddr
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Maybe peerAddr
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
TrConnect Maybe peerAddr
addr peerAddr
peerAddr)
                      Snocket m socket peerAddr -> socket -> peerAddr -> m ()
forall (m :: * -> *) fd addr.
Snocket m fd addr -> fd -> addr -> m ()
connect Snocket m socket peerAddr
cmSnocket socket
socket peerAddr
peerAddr
                        m () -> (SomeException -> m ()) -> m ()
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` \SomeException
e -> do
                          Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Maybe peerAddr
-> peerAddr
-> SomeException
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Maybe peerAddr
-> peerAddr
-> SomeException
-> ConnectionManagerTrace peerAddr handlerTrace
TrConnectError Maybe peerAddr
addr peerAddr
peerAddr SomeException
e)
                          -- the handler attached by `bracketOnError` will
                          -- reset the state
                          SomeException -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwIO SomeException
e
                      peerAddr
localAddress <- Snocket m socket peerAddr -> socket -> m peerAddr
forall (m :: * -> *) fd addr. Snocket m fd addr -> fd -> m addr
getLocalAddr Snocket m socket peerAddr
cmSnocket socket
socket
                      let connId :: ConnectionId peerAddr
connId = ConnectionId :: forall addr. addr -> addr -> ConnectionId addr
ConnectionId { peerAddr
localAddress :: peerAddr
localAddress :: peerAddr
localAddress
                                                , remoteAddress :: peerAddr
remoteAddress = peerAddr
peerAddr
                                                }
                      (socket, ConnectionId peerAddr)
-> m (socket, ConnectionId peerAddr)
forall (m :: * -> *) a. Monad m => a -> m a
return (socket
socket, ConnectionId peerAddr
connId)

                --
                -- fork connection handler; it will unmask exceptions
                --

                Async m ()
connThread <-
                  StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> MutableConnState peerAddr handle handleError version m
-> socket
-> ConnectionId peerAddr
-> PromiseWriter m (Either handleError (handle, version))
-> ConnectionHandlerFn
     handlerTrace socket peerAddr handle handleError version m
-> m (Async m ())
forkConnectionHandler
                    StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar MutableConnState peerAddr handle handleError version m
mutableConnState socket
socket ConnectionId peerAddr
connId PromiseWriter m (Either handleError (handle, version))
writer ConnectionHandlerFn
  handlerTrace socket peerAddr handle handleError version m
handler
                (ConnectionId peerAddr, Async m ())
-> m (ConnectionId peerAddr, Async m ())
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionId peerAddr
connId, Async m ()
connThread)

            (Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
trans, Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion) <- STM
  m
  (Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))),
   Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))),
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> m (Maybe
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))),
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$ do
              ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar

              -- @
              --  Connected : ReservedOutboundState
              --            → UnnegotiatedState Outbound
              -- @
              case ConnectionState peerAddr handle handleError version m
connState of
                ConnectionState peerAddr handle handleError version m
ReservedOutboundState -> do
                  let connState' :: ConnectionState peerAddr handle handleError version m
connState' = Provenance
-> ConnectionId peerAddr
-> Async m ()
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Provenance
-> ConnectionId peerAddr
-> Async m ()
-> ConnectionState peerAddr handle handleError version m
UnnegotiatedState Provenance
provenance ConnectionId peerAddr
connId Async m ()
connThread
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'
                         , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                         )
                TerminatingState {} ->
                  (Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing, Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing)
                TerminatedState {} ->
                  (Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing, Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing)
                ConnectionState peerAddr handle handleError version m
_ ->
                  (Maybe
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                         , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                   (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
RequestOutboundConnection
                                     (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                     (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState))
                                   )
                                )
                         )

            (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
trans
            (ConnectionManagerTrace peerAddr handlerTrace -> m ())
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace) -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (ConnectionManagerTrace peerAddr handlerTrace -> m ())
-> (() -> m ())
-> ConnectionManagerTrace peerAddr handlerTrace
-> m ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> () -> m ()
forall (m :: * -> *) a. MonadEvaluate m => a -> m a
evaluate (() -> m ()) -> (() -> ()) -> () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> () -> ()
forall a. HasCallStack => Bool -> a -> a
assert Bool
True)
                      Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion
            StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

            Either handleError (handle, version)
res <- STM m (Either handleError (handle, version))
-> m (Either handleError (handle, version))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (PromiseReader m (Either handleError (handle, version))
-> STM m (Either handleError (handle, version))
forall (m :: * -> *) a. PromiseReader m a -> STM m a
readPromise PromiseReader m (Either handleError (handle, version))
reader)
            case Either handleError (handle, version)
res of
              Left handleError
handleError -> do
                [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
transitions <- STM
  m
  [Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))]
-> m [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
 -> m [Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))])
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
-> m [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. (a -> b) -> a -> b
$ do
                  ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar

                  let connState' :: ConnectionState peerAddr handle handleError version m
connState' =
                        case handleError -> HandleErrorType
classifyHandleError handleError
handleError of
                          HandleErrorType
HandshakeFailure ->
                            ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatingState ConnectionId peerAddr
connId Async m ()
connThread
                                            (handleError -> Maybe handleError
forall a. a -> Maybe a
Just handleError
handleError)
                          HandleErrorType
HandshakeProtocolViolation ->
                            Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState (handleError -> Maybe handleError
forall a. a -> Maybe a
Just handleError
handleError)
                      transition :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition = ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'
                      absConnState :: AbstractState
absConnState = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
                      shouldTrace :: Bool
shouldTrace = AbstractState
absConnState AbstractState -> AbstractState -> Bool
forall a. Eq a => a -> a -> Bool
/= AbstractState
TerminatedSt

                  -- 'handleError' might be either a handshake negotiation
                  -- a protocol failure (an IO exception, a timeout or
                  -- codec failure).  In the first case we should not reset
                  -- the connection as this is not a protocol error.
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'

                  Bool
updated <-
                    StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> (ConnectionManagerState peerAddr handle handleError version m
    -> (ConnectionManagerState peerAddr handle handleError version m,
        Bool))
-> STM m Bool
forall (m :: * -> *) a b.
MonadSTM m =>
StrictTMVar m a -> (a -> (a, b)) -> STM m b
modifyTMVarPure
                      StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                      ( \ConnectionManagerState peerAddr handle handleError version m
state ->
                        case peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state of
                          Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> (ConnectionManagerState peerAddr handle handleError version m
state, Bool
False)
                          Just MutableConnState peerAddr handle handleError version m
mutableConnState'  ->
                            if MutableConnState peerAddr handle handleError version m
mutableConnState' MutableConnState peerAddr handle handleError version m
-> MutableConnState peerAddr handle handleError version m -> Bool
forall a. Eq a => a -> a -> Bool
== MutableConnState peerAddr handle handleError version m
mutableConnState
                              then (peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionManagerState peerAddr handle handleError version m
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state , Bool
True)
                              else (ConnectionManagerState peerAddr handle handleError version m
state                     , Bool
False)
                      )

                  if Bool
updated
                     then
                    -- Key was present in the dictionary (stateVar) and
                    -- removed so we trace the removal.
                      [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Transition'
    (MaybeUnknown
       (ConnectionState peerAddr handle handleError version m))]
 -> STM
      m
      [Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))])
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall a b. (a -> b) -> a -> b
$
                        if Bool
shouldTrace
                           then [ Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
transition
                                , Transition :: forall state. state -> state -> Transition' state
Transition
                                   { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing)
                                   , toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown
                                   }
                                ]
                           else [ Transition :: forall state. state -> state -> Transition' state
Transition
                                   { fromState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
fromState = ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing)
                                   , toState :: MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
toState   = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
forall state. MaybeUnknown state
Unknown
                                   }
                                ]
                    -- Key was not present in the dictionary (stateVar),
                    -- so we do not trace anything as it was already traced upon
                    -- deletion.
                    --
                    -- OR
                    --
                    -- Key was overwritten in the dictionary (stateVar),
                    -- so we do not trace anything as it was already traced upon
                    -- overwriting.
                     else [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
-> STM
     m
     [Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))]
forall (m :: * -> *) a. Monad m => a -> m a
return [ ]


                (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> [Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))]
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) [Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))]
transitions
                StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

                Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
Disconnected ConnectionId peerAddr
connId (handleError -> Maybe handleError
forall a. a -> Maybe a
Just handleError
handleError))

              Right (handle
handle, version
version) -> do
                let dataFlow :: DataFlow
dataFlow = version -> DataFlow
connectionDataFlow version
version
                -- We can safely overwrite the state: after successful
                -- `connect` it's not possible to have a race condition
                -- with any other inbound thread.  We are also guaranteed
                -- to have exclusive access as an outbound thread.
                Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition <- STM
  m
  (Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))))
-> m (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
 -> m (Maybe
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m)))))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
-> m (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall a b. (a -> b) -> a -> b
$ do
                  ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                  case ConnectionState peerAddr handle handleError version m
connState of
                    UnnegotiatedState {} ->
                      case DataFlow
dataFlow of
                        DataFlow
Unidirectional -> do
                          -- @
                          --  Negotiated^{Unidirectional}_{Outbound}
                          --    : UnnegotiatedState Outbound
                          --    → OutboundUniState Outbound
                          -- @
                          let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
OutboundUniState ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                          StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                          Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                        DataFlow
Duplex -> do
                          -- @
                          --  Negotiated^{Duplex}_{Outbound}
                          --    : UnnegotiatedState Outbound
                          --    → OutboundDupState^\tau  Outbound
                          -- @
                          let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Ticking
                          StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                          case InResponderMode
  muxMode (ControlChannel m (NewConnection peerAddr handle))
inboundGovernorControlChannel of
                            InResponderMode ControlChannel m (NewConnection peerAddr handle)
controlChannel ->
                              ControlChannel m (NewConnection peerAddr handle)
-> ConnectionId peerAddr -> DataFlow -> handle -> STM m ()
forall (m :: * -> *) peerAddr handle.
ControlChannel m (NewConnection peerAddr handle)
-> ConnectionId peerAddr -> DataFlow -> handle -> STM m ()
ControlChannel.newOutboundConnection
                                               ControlChannel m (NewConnection peerAddr handle)
controlChannel ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle
                            InResponderMode
  muxMode (ControlChannel m (NewConnection peerAddr handle))
NotInResponderMode -> () -> STM m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                          Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return (Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> Maybe
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                    TerminatedState Maybe handleError
_ ->
                      Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing
                    ConnectionState peerAddr handle handleError version m
_ ->
                      let st :: AbstractState
st = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState) in
                      ConnectionManagerError peerAddr
-> STM
     m
     (Maybe
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))))
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr
-> AbstractState -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr
-> AbstractState -> CallStack -> ConnectionManagerError peerAddr
ForbiddenOperation peerAddr
peerAddr AbstractState
st))
                (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr)
                          Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition
                StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
                Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return (Connected peerAddr handle handleError
 -> m (Connected peerAddr handle handleError))
-> Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall a b. (a -> b) -> a -> b
$ case Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
mbTransition of
                  Just Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
_  -> ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
Connected    ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle
                  Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
Nothing -> ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
Disconnected ConnectionId peerAddr
connId Maybe handleError
forall a. Maybe a
Nothing

          Right (There ConnectionId peerAddr
connId) -> do
            -- We can only enter the 'There' case if there is an inbound
            -- connection, and we are about to reuse it, but we need to wait
            -- for handshake.
            (Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
etr, Connected peerAddr handle handleError
connected) <- STM
  m
  (Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace),
   Connected peerAddr handle handleError)
-> m (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Either
      (TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
      (ConnectionManagerTrace peerAddr handlerTrace),
    Connected peerAddr handle handleError)
 -> m (Either
         (TransitionTrace
            peerAddr (ConnectionState peerAddr handle handleError version m))
         (ConnectionManagerTrace peerAddr handlerTrace),
       Connected peerAddr handle handleError))
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
-> m (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall a b. (a -> b) -> a -> b
$ do
              ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
              case ConnectionState peerAddr handle handleError version m
connState of
                ReservedOutboundState {} ->
                  ConnectionManagerError peerAddr
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM
                    ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr -> CallStack -> ConnectionManagerError peerAddr
ImpossibleState (ConnectionId peerAddr -> peerAddr
forall addr. ConnectionId addr -> addr
remoteAddress ConnectionId peerAddr
connId)))
                UnnegotiatedState Provenance
Outbound ConnectionId peerAddr
_ Async m ()
_ ->
                  ConnectionManagerError (ConnectionId peerAddr)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM
                    ((CallStack -> ConnectionManagerError (ConnectionId peerAddr))
-> ConnectionManagerError (ConnectionId peerAddr)
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (Provenance
-> ConnectionId peerAddr
-> CallStack
-> ConnectionManagerError (ConnectionId peerAddr)
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance ConnectionId peerAddr
connId))

                UnnegotiatedState Provenance
Inbound ConnectionId peerAddr
_ Async m ()
_ ->
                  -- await for connection negotiation
                  STM
  m
  (Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace),
   Connected peerAddr handle handleError)
forall (m :: * -> *) a. MonadSTM m => STM m a
retry

                OutboundUniState {} ->
                  ConnectionManagerError (ConnectionId peerAddr)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError (ConnectionId peerAddr))
-> ConnectionManagerError (ConnectionId peerAddr)
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (Provenance
-> ConnectionId peerAddr
-> CallStack
-> ConnectionManagerError (ConnectionId peerAddr)
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance ConnectionId peerAddr
connId))

                OutboundDupState {} ->
                  ConnectionManagerError (ConnectionId peerAddr)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError (ConnectionId peerAddr))
-> ConnectionManagerError (ConnectionId peerAddr)
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (Provenance
-> ConnectionId peerAddr
-> CallStack
-> ConnectionManagerError (ConnectionId peerAddr)
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance ConnectionId peerAddr
connId))

                OutboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
_dataFlow ->
                  let tr :: AbstractState
tr = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState) in
                  ConnectionManagerError peerAddr
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (peerAddr
-> AbstractState -> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
peerAddr
-> AbstractState -> CallStack -> ConnectionManagerError peerAddr
ForbiddenOperation peerAddr
peerAddr AbstractState
tr))

                InboundIdleState ConnectionId peerAddr
_connId Async m ()
connThread handle
handle dataFlow :: DataFlow
dataFlow@DataFlow
Duplex -> do
                  -- @
                  --   Awake^{Duplex}_{Local} : InboundIdleState Duplex
                  --                          → OutboundState^\tau Duplex
                  -- @
                  -- This transition can happen if there are concurrent
                  -- `includeInboudConnection` and `requestOutboundConnection`
                  -- calls.
                  let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Ticking
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (Either
   (TransitionTrace
      peerAddr (ConnectionState peerAddr handle handleError version m))
   (ConnectionManagerTrace peerAddr handlerTrace),
 Connected peerAddr handle handleError)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return ( TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. a -> Either a b
Left (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace
                                  peerAddr
peerAddr
                                  (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'))
                         , ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
Connected ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle
                         )

                InboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
Unidirectional ->
                  ConnectionManagerError peerAddr
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM
                    ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
ForbiddenConnection ConnectionId peerAddr
connId))

                InboundState ConnectionId peerAddr
_connId Async m ()
connThread handle
handle dataFlow :: DataFlow
dataFlow@DataFlow
Duplex -> do
                  -- @
                  --   PromotedToWarm^{Duplex}_{Local} : InboundState Duplex
                  --                                   → DuplexState
                  -- @
                  --
                  -- Note: this is unlikely to observe: @There connId@ only
                  -- appears if an inbound connection is unnegotiated, it is
                  -- more likely to observe the
                  -- @
                  --    InboundIdleState Duplex -> OutboundDupState
                  -- @
                  -- transition.
                  let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
DuplexState ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (Either
   (TransitionTrace
      peerAddr (ConnectionState peerAddr handle handleError version m))
   (ConnectionManagerTrace peerAddr handlerTrace),
 Connected peerAddr handle handleError)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return ( TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. a -> Either a b
Left (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace
                                  peerAddr
peerAddr
                                  (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'))
                         , ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> DataFlow -> handle -> Connected peerAddr handle handleError
Connected ConnectionId peerAddr
connId DataFlow
dataFlow handle
handle
                         )

                InboundState ConnectionId peerAddr
_ Async m ()
_ handle
_ DataFlow
Unidirectional ->
                  ConnectionManagerError peerAddr
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError peerAddr)
-> ConnectionManagerError peerAddr
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
forall peerAddr.
ConnectionId peerAddr
-> CallStack -> ConnectionManagerError peerAddr
ForbiddenConnection ConnectionId peerAddr
connId))

                DuplexState {} ->
                  ConnectionManagerError (ConnectionId peerAddr)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) e a.
(MonadSTM m, MonadThrow (STM m), Exception e) =>
e -> STM m a
throwSTM ((CallStack -> ConnectionManagerError (ConnectionId peerAddr))
-> ConnectionManagerError (ConnectionId peerAddr)
forall a. HasCallStack => (CallStack -> a) -> a
withCallStack (Provenance
-> ConnectionId peerAddr
-> CallStack
-> ConnectionManagerError (ConnectionId peerAddr)
forall peerAddr.
Provenance
-> peerAddr -> CallStack -> ConnectionManagerError peerAddr
ConnectionExists Provenance
provenance ConnectionId peerAddr
connId))

                TerminatingState ConnectionId peerAddr
_connId Async m ()
_connThread Maybe handleError
handleError ->
                  (Either
   (TransitionTrace
      peerAddr (ConnectionState peerAddr handle handleError version m))
   (ConnectionManagerTrace peerAddr handlerTrace),
 Connected peerAddr handle handleError)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return ( ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (Provenance
-> ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> ConnectionId peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
TrTerminatingConnection Provenance
provenance ConnectionId peerAddr
connId)
                         , ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
Disconnected ConnectionId peerAddr
connId Maybe handleError
handleError
                         )
                TerminatedState Maybe handleError
handleError ->
                  (Either
   (TransitionTrace
      peerAddr (ConnectionState peerAddr handle handleError version m))
   (ConnectionManagerTrace peerAddr handlerTrace),
 Connected peerAddr handle handleError)
-> STM
     m
     (Either
        (TransitionTrace
           peerAddr (ConnectionState peerAddr handle handleError version m))
        (ConnectionManagerTrace peerAddr handlerTrace),
      Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return ( ConnectionManagerTrace peerAddr handlerTrace
-> Either
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
     (ConnectionManagerTrace peerAddr handlerTrace)
forall a b. b -> Either a b
Right (Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
TrTerminatedConnection Provenance
provenance
                                                         (ConnectionId peerAddr -> peerAddr
forall addr. ConnectionId addr -> addr
remoteAddress ConnectionId peerAddr
connId))
                         , ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
forall peerAddr handle handleError.
ConnectionId peerAddr
-> Maybe handleError -> Connected peerAddr handle handleError
Disconnected ConnectionId peerAddr
connId Maybe handleError
handleError
                         )

            case Either
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
  (ConnectionManagerTrace peerAddr handlerTrace)
etr of
              Left TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
tr'  -> Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer TransitionTrace
  peerAddr (ConnectionState peerAddr handle handleError version m)
tr'
              Right ConnectionManagerTrace peerAddr handlerTrace
tr' -> Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer   ConnectionManagerTrace peerAddr handlerTrace
tr'
            StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
            Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return Connected peerAddr handle handleError
connected

          -- Connection manager has a connection which can be reused.
          Right (Here Connected peerAddr handle handleError
connected) -> do
            StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
            Connected peerAddr handle handleError
-> m (Connected peerAddr handle handleError)
forall (m :: * -> *) a. Monad m => a -> m a
return Connected peerAddr handle handleError
connected


    unregisterOutboundConnectionImpl
        :: StrictTMVar m
            (ConnectionManagerState peerAddr handle handleError version m)
        -> peerAddr
        -> m (OperationResult AbstractState)
    unregisterOutboundConnectionImpl :: StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
unregisterOutboundConnectionImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar peerAddr
peerAddr = do
      Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer (Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
Provenance
-> peerAddr -> ConnectionManagerTrace peerAddr handlerTrace
TrUnregisterConnection Provenance
Outbound peerAddr
peerAddr)
      (DemoteToColdLocal
  peerAddr handlerTrace handle handleError version m
transition, Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion)
        <- STM
  m
  (DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m,
   Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (DemoteToColdLocal
      peerAddr handlerTrace handle handleError version m,
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> m (DemoteToColdLocal
         peerAddr handlerTrace handle handleError version m,
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$ do
        ConnectionManagerState peerAddr handle handleError version m
state <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
        case peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state of
          -- if the connection errored, it will remove itself from the state.
          -- Calling 'unregisterOutboundConnection' is a no-op in this case.
          Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (f :: * -> *) a. Applicative f => a -> f a
pure ( Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
Maybe
  (Transition
     (ConnectionState peerAddr handle handleError version m))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalNoop Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing AbstractState
UnknownConnectionSt
                          , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing)

          Just MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar } -> do
            ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
            let st :: AbstractState
st = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
            case ConnectionState peerAddr handle handleError version m
connState of
              -- In any of the following three states unregistering is not
              -- supported.  'requestOutboundConnection' is a synchronous
              -- operation which returns only once the connection is
              -- negotiated.
              ConnectionState peerAddr handle handleError version m
ReservedOutboundState ->
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ((DemoteToColdLocal
    peerAddr handlerTrace handle handleError version m,
  Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> STM
      m
      (DemoteToColdLocal
         peerAddr handlerTrace handle handleError version m,
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> (DemoteToColdLocal
      peerAddr handlerTrace handle handleError version m,
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$
                  ( ConnectionManagerTrace peerAddr handlerTrace
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
ConnectionManagerTrace peerAddr handlerTrace
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalError
                     (peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
TrForbiddenOperation peerAddr
peerAddr AbstractState
st)
                     AbstractState
st
                  , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                  )

              UnnegotiatedState Provenance
_ ConnectionId peerAddr
_ Async m ()
_ ->
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ((DemoteToColdLocal
    peerAddr handlerTrace handle handleError version m,
  Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> STM
      m
      (DemoteToColdLocal
         peerAddr handlerTrace handle handleError version m,
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> (DemoteToColdLocal
      peerAddr handlerTrace handle handleError version m,
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$
                  ( ConnectionManagerTrace peerAddr handlerTrace
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
ConnectionManagerTrace peerAddr handlerTrace
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalError
                     (peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
TrForbiddenOperation peerAddr
peerAddr AbstractState
st)
                     AbstractState
st
                  , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                  )

              OutboundUniState ConnectionId peerAddr
connId Async m ()
connThread handle
handle -> do
                -- @
                --   DemotedToCold^{Unidirectional}_{Local}
                --     : OutboundState Unidirectional
                --     → OutboundIdleState Unidirectional
                -- @
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
OutboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                                                   DataFlow
Unidirectional
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( ConnectionId peerAddr
-> Async m ()
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Transition
     (ConnectionState peerAddr handle handleError version m)
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemotedToColdLocal ConnectionId peerAddr
connId Async m ()
connThread StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                          (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Expired -> do
                -- @
                --   DemotedToCold^{Duplex}_{Local}
                --     : OutboundState Duplex
                --     → OutboundIdleState^\tau
                -- @
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
OutboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                                                   DataFlow
Duplex
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( ConnectionId peerAddr
-> Async m ()
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Transition
     (ConnectionState peerAddr handle handleError version m)
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemotedToColdLocal ConnectionId peerAddr
connId Async m ()
connThread StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                          (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Ticking -> do
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
InboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
handle DataFlow
Duplex
                    tr :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr = ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'

                Int
numberOfConns <- ConnectionManagerState peerAddr handle handleError version m
-> STM m Int
countIncomingConnections ConnectionManagerState peerAddr handle handleError version m
state

                -- use 'numberOfConns + 1' because we want to know if we
                -- actually let this connection evolve if we need to make
                -- room for them by pruning.  This is because
                -- 'countIncomingConnections' does not count 'OutboundDupState'
                -- as an inbound connection, but does so for 'InboundIdleState'.
                let numberToPrune :: Int
numberToPrune =
                      Int
numberOfConns Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
                      Int -> Int -> Int
forall a. Num a => a -> a -> a
- Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
                          (AcceptedConnectionsLimit -> Word32
acceptedConnectionsHardLimit AcceptedConnectionsLimit
cmConnectionsLimits)
                if Int
numberToPrune Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
                then do
                  (Bool
_, PruneAction m
prune)
                    <- peerAddr
-> Int
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Async m ()
-> STM m (Bool, PruneAction m)
mkPruneAction peerAddr
peerAddr Int
numberToPrune ConnectionManagerState peerAddr handle handleError version m
state ConnectionState peerAddr handle handleError version m
connState' StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar Async m ()
connThread
                  (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return
                    ( PruneAction m
-> Either
     (ConnectionState peerAddr handle handleError version m)
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
PruneAction m
-> Either
     (ConnectionState peerAddr handle handleError version m)
     (Transition
        (ConnectionState peerAddr handle handleError version m))
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
PruneConnections PruneAction m
prune (ConnectionState peerAddr handle handleError version m
-> Either
     (ConnectionState peerAddr handle handleError version m)
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a b. a -> Either a b
Left ConnectionState peerAddr handle handleError version m
connState)
                    , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                    )

                else do
                  -- @
                  --   DemotedToCold^{Duplex}_{Local}
                  --     : OutboundState^\tau Duplex
                  --     → InboundIdleState^\tau Duplex
                  -- @
                  -- does not require to perform any additional io action (we
                  -- already updated 'connVar').
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
Maybe
  (Transition
     (ConnectionState peerAddr handle handleError version m))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalNoop (Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr) AbstractState
st
                         , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                         )

              OutboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handleError DataFlow
_dataFlow ->
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
Maybe
  (Transition
     (ConnectionState peerAddr handle handleError version m))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalNoop Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              -- TODO: This assertion is benign and also hit rarely (once per
              -- 100_000 simulations)
              InboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
_dataFlow ->
                -- assert (dataFlow == Duplex) $
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
Maybe
  (Transition
     (ConnectionState peerAddr handle handleError version m))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalNoop Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              InboundState ConnectionId peerAddr
connId Async m ()
_connThread handle
_handle DataFlow
dataFlow -> do
                let mbAssertion :: Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion =
                      if DataFlow
dataFlow DataFlow -> DataFlow -> Bool
forall a. Eq a => a -> a -> Bool
== DataFlow
Duplex
                         then Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                         else ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                      (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
UnregisterOutboundConnection
                                        (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                        AbstractState
st)
                                   )
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return
                  ( ConnectionManagerTrace peerAddr handlerTrace
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
ConnectionManagerTrace peerAddr handlerTrace
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalError
                     (peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
peerAddr
-> AbstractState -> ConnectionManagerTrace peerAddr handlerTrace
TrForbiddenOperation peerAddr
peerAddr AbstractState
st)
                     AbstractState
st
                  , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion
                  )

              DuplexState ConnectionId peerAddr
connId Async m ()
connThread handle
handle -> do
                -- @
                --   DemotedToCold^{Duplex}_{Local} : DuplexState
                --                                  → InboundState Duplex
                -- @
                --
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
InboundState ConnectionId peerAddr
connId Async m ()
connThread handle
handle DataFlow
Duplex
                    tr :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr = ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'

                -- @
                -- DemotedToCold^{Duplex}_{Local} : DuplexState
                --                                → InboundState Duplex
                -- @
                -- does not require to perform any additional io action (we
                -- already updated 'connVar').
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
Maybe
  (Transition
     (ConnectionState peerAddr handle handleError version m))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalNoop (Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> Maybe a
Just Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr) AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              TerminatingState ConnectionId peerAddr
_connId Async m ()
_connThread Maybe handleError
_handleError ->
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
Maybe
  (Transition
     (ConnectionState peerAddr handle handleError version m))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalNoop Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              TerminatedState Maybe handleError
_handleError ->
                (DemoteToColdLocal
   peerAddr handlerTrace handle handleError version m,
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (DemoteToColdLocal
        peerAddr handlerTrace handle handleError version m,
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
forall peerAddr handlerTrace handle handleError version
       (m :: * -> *).
Maybe
  (Transition
     (ConnectionState peerAddr handle handleError version m))
-> AbstractState
-> DemoteToColdLocal
     peerAddr handlerTrace handle handleError version m
DemoteToColdLocalNoop Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
forall a. Maybe a
Nothing AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

      Maybe (ConnectionManagerTrace peerAddr handlerTrace)
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall (m :: * -> *) a.
Applicative m =>
Maybe a -> (a -> m ()) -> m ()
whenJust Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion ((ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ())
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \ConnectionManagerTrace peerAddr handlerTrace
tr' -> do
        Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer ConnectionManagerTrace peerAddr handlerTrace
tr'
        Any -> Any
_ <- (Any -> Any) -> m (Any -> Any)
forall (m :: * -> *) a. MonadEvaluate m => a -> m a
evaluate (Bool -> Any -> Any
forall a. HasCallStack => Bool -> a -> a
assert Bool
False)
        () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

      case DemoteToColdLocal
  peerAddr handlerTrace handle handleError version m
transition of
        DemotedToColdLocal ConnectionId peerAddr
connId Async m ()
connThread StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr -> do
          Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr)
          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
          TVar m Bool
timeoutVar <- DiffTime -> m (TVar m Bool)
forall (m :: * -> *). MonadTimer m => DiffTime -> m (TVar m Bool)
registerDelay DiffTime
cmOutboundIdleTimeout
          Either
  (ConnectionState peerAddr handle handleError version m)
  (ConnectionState peerAddr handle handleError version m)
r <- STM
  m
  (Either
     (ConnectionState peerAddr handle handleError version m)
     (ConnectionState peerAddr handle handleError version m))
-> m (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (Either
      (ConnectionState peerAddr handle handleError version m)
      (ConnectionState peerAddr handle handleError version m))
 -> m (Either
         (ConnectionState peerAddr handle handleError version m)
         (ConnectionState peerAddr handle handleError version m)))
-> STM
     m
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
-> m (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall a b. (a -> b) -> a -> b
$ FirstToFinish
  (STM m)
  (Either
     (ConnectionState peerAddr handle handleError version m)
     (ConnectionState peerAddr handle handleError version m))
-> STM
     m
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a. FirstToFinish m a -> m a
runFirstToFinish (FirstToFinish
   (STM m)
   (Either
      (ConnectionState peerAddr handle handleError version m)
      (ConnectionState peerAddr handle handleError version m))
 -> STM
      m
      (Either
         (ConnectionState peerAddr handle handleError version m)
         (ConnectionState peerAddr handle handleError version m)))
-> FirstToFinish
     (STM m)
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
-> STM
     m
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall a b. (a -> b) -> a -> b
$
               STM
  m
  (Either
     (ConnectionState peerAddr handle handleError version m)
     (ConnectionState peerAddr handle handleError version m))
-> FirstToFinish
     (STM m)
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a. m a -> FirstToFinish m a
FirstToFinish (do ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                                 Bool -> STM m ()
forall (m :: * -> *). MonadSTM m => Bool -> STM m ()
check (case ConnectionState peerAddr handle handleError version m
connState of
                                          OutboundIdleState {} -> Bool
False
                                          ConnectionState peerAddr handle handleError version m
_                    -> Bool
True
                                       )
                                 Either
  (ConnectionState peerAddr handle handleError version m)
  (ConnectionState peerAddr handle handleError version m)
-> STM
     m
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a. Monad m => a -> m a
return (ConnectionState peerAddr handle handleError version m
-> Either
     (ConnectionState peerAddr handle handleError version m)
     (ConnectionState peerAddr handle handleError version m)
forall a b. a -> Either a b
Left ConnectionState peerAddr handle handleError version m
connState)
                             )
            FirstToFinish
  (STM m)
  (Either
     (ConnectionState peerAddr handle handleError version m)
     (ConnectionState peerAddr handle handleError version m))
-> FirstToFinish
     (STM m)
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
-> FirstToFinish
     (STM m)
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall a. Semigroup a => a -> a -> a
<> STM
  m
  (Either
     (ConnectionState peerAddr handle handleError version m)
     (ConnectionState peerAddr handle handleError version m))
-> FirstToFinish
     (STM m)
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall (m :: * -> *) a. m a -> FirstToFinish m a
FirstToFinish (do Bool
b <- TVar m Bool -> STM m Bool
forall (m :: * -> *) a. MonadSTM m => TVar m a -> STM m a
LazySTM.readTVar TVar m Bool
timeoutVar
                                 Bool -> STM m ()
forall (m :: * -> *). MonadSTM m => Bool -> STM m ()
check Bool
b
                                 ConnectionState peerAddr handle handleError version m
-> Either
     (ConnectionState peerAddr handle handleError version m)
     (ConnectionState peerAddr handle handleError version m)
forall a b. b -> Either a b
Right (ConnectionState peerAddr handle handleError version m
 -> Either
      (ConnectionState peerAddr handle handleError version m)
      (ConnectionState peerAddr handle handleError version m))
-> STM m (ConnectionState peerAddr handle handleError version m)
-> STM
     m
     (Either
        (ConnectionState peerAddr handle handleError version m)
        (ConnectionState peerAddr handle handleError version m))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
                             )
          case Either
  (ConnectionState peerAddr handle handleError version m)
  (ConnectionState peerAddr handle handleError version m)
r of
            Right ConnectionState peerAddr handle handleError version m
connState -> do
              let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatingState ConnectionId peerAddr
connId Async m ()
connThread Maybe handleError
forall a. Maybe a
Nothing
              STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM m () -> m ()) -> STM m () -> m ()
forall a b. (a -> b) -> a -> b
$ StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
              Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr
                                   (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'))
              StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
              -- We rely on the `finally` handler of connection thread to:
              --
              -- - close the socket,
              -- - set the state to 'TerminatedState'
              -- - 'throwTo' avoids blocking until 'cmTimeWaitTimeout' expires.
              ThreadId m -> AsyncCancelled -> m ()
forall (m :: * -> *) e.
(MonadFork m, Exception e) =>
ThreadId m -> e -> m ()
throwTo (Async m () -> ThreadId m
forall (m :: * -> *) a. MonadAsync m => Async m a -> ThreadId m
asyncThreadId Async m ()
connThread)
                      AsyncCancelled
AsyncCancelled
              OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (AbstractState -> OperationResult AbstractState
forall a. a -> OperationResult a
OperationSuccess (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (MaybeUnknown
   (ConnectionState peerAddr handle handleError version m)
 -> AbstractState)
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState'))

            Left ConnectionState peerAddr handle handleError version m
connState  | ConnectionState peerAddr handle handleError version m -> Bool
forall peerAddr handle handleError version (m :: * -> *).
ConnectionState peerAddr handle handleError version m -> Bool
connectionTerminated ConnectionState peerAddr handle handleError version m
connState
                           ->
              OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (AbstractState -> OperationResult AbstractState
forall a. a -> OperationResult a
OperationSuccess (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (MaybeUnknown
   (ConnectionState peerAddr handle handleError version m)
 -> AbstractState)
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState))
            Left ConnectionState peerAddr handle handleError version m
connState ->
              OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (AbstractState -> OperationResult AbstractState
forall a. AbstractState -> OperationResult a
UnsupportedState (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (MaybeUnknown
   (ConnectionState peerAddr handle handleError version m)
 -> AbstractState)
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall a b. (a -> b) -> a -> b
$ ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState))

        PruneConnections PruneAction m
prune Either
  (ConnectionState peerAddr handle handleError version m)
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
eTr -> do
          (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> m ())
-> Either
     (ConnectionState peerAddr handle handleError version m)
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> TransitionTrace
         peerAddr (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr) Either
  (ConnectionState peerAddr handle handleError version m)
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
eTr
          PruneAction m -> m ()
forall (m :: * -> *). PruneAction m -> m ()
runPruneAction PruneAction m
prune
          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
          OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (AbstractState -> OperationResult AbstractState
forall a. a -> OperationResult a
OperationSuccess (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState ((ConnectionState peerAddr handle handleError version m
 -> MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
-> Either
     (ConnectionState peerAddr handle handleError version m)
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. Transition' state -> state
fromState Either
  (ConnectionState peerAddr handle handleError version m)
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
eTr)))

        DemoteToColdLocalError ConnectionManagerTrace peerAddr handlerTrace
trace AbstractState
st -> do
          Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer ConnectionManagerTrace peerAddr handlerTrace
trace
          OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (AbstractState -> OperationResult AbstractState
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st)

        DemoteToColdLocalNoop Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
tr AbstractState
a -> do
          (TransitionTrace
   peerAddr (ConnectionState peerAddr handle handleError version m)
 -> m ())
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
-> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer) (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> TransitionTrace
      peerAddr (ConnectionState peerAddr handle handleError version m))
-> Maybe
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> Maybe
     (TransitionTrace
        peerAddr (ConnectionState peerAddr handle handleError version m))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
tr)
          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
          OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (AbstractState -> OperationResult AbstractState
forall a. a -> OperationResult a
OperationSuccess AbstractState
a)


    -- Needs to mask the STM action and the tracing for the case of an async
    -- exception falls right between the STM commit and the IO tracing. This
    -- guarantees that the same order of transitions and its trace.
    promotedToWarmRemoteImpl
        :: StrictTMVar m (ConnectionManagerState peerAddr handle handleError version m)
        -> peerAddr
        -> m (OperationResult AbstractState)
    promotedToWarmRemoteImpl :: StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
promotedToWarmRemoteImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar peerAddr
peerAddr = m (OperationResult AbstractState)
-> m (OperationResult AbstractState)
forall (m :: * -> *) a. MonadMask m => m a -> m a
mask_ (m (OperationResult AbstractState)
 -> m (OperationResult AbstractState))
-> m (OperationResult AbstractState)
-> m (OperationResult AbstractState)
forall a b. (a -> b) -> a -> b
$ do
      (OperationResult
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
result, Maybe (PruneAction m)
pruneTr, Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion) <- STM
  m
  (OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))),
   Maybe (PruneAction m),
   Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (OperationResult
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))),
    Maybe (PruneAction m),
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> m (OperationResult
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))),
       Maybe (PruneAction m),
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$ do
        ConnectionManagerState peerAddr handle handleError version m
state <- StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
        let mbConnVar :: Maybe (MutableConnState peerAddr handle handleError version m)
mbConnVar = peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr ConnectionManagerState peerAddr handle handleError version m
state
        case Maybe (MutableConnState peerAddr handle handleError version m)
mbConnVar of
          Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
UnknownConnectionSt
                            , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                            , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                            )
          Just MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar } -> do
            ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
            let st :: AbstractState
st = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
            case ConnectionState peerAddr handle handleError version m
connState of
              ReservedOutboundState {} -> do
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
PromotedToWarmRemote
                                  Maybe (ConnectionId peerAddr)
forall a. Maybe a
Nothing
                                  AbstractState
st)
                              )
                       )
              UnnegotiatedState Provenance
_ ConnectionId peerAddr
connId Async m ()
_ ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
PromotedToWarmRemote
                                  (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                  AbstractState
st)
                              )
                       )
              OutboundUniState ConnectionId peerAddr
connId Async m ()
_connThread handle
_handle ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
PromotedToWarmRemote
                                  (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                  AbstractState
st)
                              )
                       )
              OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
_expired -> do
                -- @
                --   PromotedToWarm^{Duplex}_{Remote} : OutboundState Duplex
                --                                    → DuplexState
                -- @
                --
                -- For connections that reach DuplexState we are not sure if
                -- this was due a connection that was established due to TCP
                -- simultaneous open or normal connect/accept. If it was
                -- established due to TCP simultaneous open a DuplexState can
                -- make us go above the Server number of connections hard limit,
                -- hence we need to prune connections.
                --
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> ConnectionState peerAddr handle handleError version m
DuplexState ConnectionId peerAddr
connId Async m ()
connThread handle
handle
                    tr :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr = ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'

                Int
numberOfConns <- ConnectionManagerState peerAddr handle handleError version m
-> STM m Int
countIncomingConnections ConnectionManagerState peerAddr handle handleError version m
state

                -- use 'numberOfConns + 1' because we want to know if we
                -- actually let this connection evolve if we need to make
                -- room for them by pruning.
                let numberToPrune :: Int
numberToPrune =
                      Int
numberOfConns Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
                      Int -> Int -> Int
forall a. Num a => a -> a -> a
- Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
                          (AcceptedConnectionsLimit -> Word32
acceptedConnectionsHardLimit AcceptedConnectionsLimit
cmConnectionsLimits)

                -- Are we above the hard limit?
                if Int
numberToPrune Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
                then do
                  (Bool
pruneSelf, PruneAction m
prune)
                    <- peerAddr
-> Int
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Async m ()
-> STM m (Bool, PruneAction m)
mkPruneAction peerAddr
peerAddr Int
numberToPrune ConnectionManagerState peerAddr handle handleError version m
state ConnectionState peerAddr handle handleError version m
connState' StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar Async m ()
connThread

                  Bool -> STM m () -> STM m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
pruneSelf)
                    (STM m () -> STM m ()) -> STM m () -> STM m ()
forall a b. (a -> b) -> a -> b
$ StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'

                  (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return
                    ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr
                    , PruneAction m -> Maybe (PruneAction m)
forall a. a -> Maybe a
Just PruneAction m
prune
                    , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                    )

                else do
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr
                         , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                         , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                         )
              OutboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
handle dataFlow :: DataFlow
dataFlow@DataFlow
Duplex -> do
                -- @
                --   Awake^{Duplex}_{Remote} : OutboundIdleState^\tau Duplex
                --                           → InboundState Duplex
                -- @
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
InboundState ConnectionId peerAddr
connId Async m ()
connThread handle
handle DataFlow
dataFlow
                    tr :: Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr = ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState'

                Int
numberOfConns <- ConnectionManagerState peerAddr handle handleError version m
-> STM m Int
countIncomingConnections ConnectionManagerState peerAddr handle handleError version m
state

                -- use 'numberOfConns + 1' because we want to know if we
                -- actually let this connection evolve if we need to make
                -- room for them by pruning.
                let numberToPrune :: Int
numberToPrune =
                      Int
numberOfConns Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
                      Int -> Int -> Int
forall a. Num a => a -> a -> a
- Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
                          (AcceptedConnectionsLimit -> Word32
acceptedConnectionsHardLimit AcceptedConnectionsLimit
cmConnectionsLimits)

                -- Are we above the hard limit?
                if Int
numberToPrune Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
                then do
                  (Bool
pruneSelf, PruneAction m
prune)
                    <- peerAddr
-> Int
-> ConnectionManagerState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
-> Async m ()
-> STM m (Bool, PruneAction m)
mkPruneAction peerAddr
peerAddr Int
numberToPrune ConnectionManagerState peerAddr handle handleError version m
state ConnectionState peerAddr handle handleError version m
connState' StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar Async m ()
connThread
                  Bool -> STM m () -> STM m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
pruneSelf)
                     (STM m () -> STM m ()) -> STM m () -> STM m ()
forall a b. (a -> b) -> a -> b
$ StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'

                  (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return
                    ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState (Maybe handleError
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
Maybe handleError
-> ConnectionState peerAddr handle handleError version m
TerminatedState Maybe handleError
forall a. Maybe a
Nothing))
                    , PruneAction m -> Maybe (PruneAction m)
forall a. a -> Maybe a
Just PruneAction m
prune
                    , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                    )

                else do
                  StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                  (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr
                         , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                         , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                         )
              OutboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
Unidirectional ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              InboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
handle DataFlow
dataFlow -> do
                -- @
                --   Awake^{dataFlow}_{Remote} : InboundIdleState Duplex
                --                             → InboundState Duplex
                -- @
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
InboundState ConnectionId peerAddr
connId Async m ()
connThread handle
handle DataFlow
dataFlow
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              InboundState ConnectionId peerAddr
connId Async m ()
_ handle
_ DataFlow
_ ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState)
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       -- already in 'InboundState'?
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
PromotedToWarmRemote
                                  (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                  AbstractState
st)
                              )
                       )
              DuplexState {} ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState)
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              TerminatingState {} ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
TerminatingSt
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              TerminatedState {} ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (PruneAction m),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
TerminatedSt
                       , Maybe (PruneAction m)
forall a. Maybe a
Nothing
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

      Maybe (ConnectionManagerTrace peerAddr handlerTrace)
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall (m :: * -> *) a.
Applicative m =>
Maybe a -> (a -> m ()) -> m ()
whenJust Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion ((ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ())
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \ConnectionManagerTrace peerAddr handlerTrace
tr' -> do
        Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer ConnectionManagerTrace peerAddr handlerTrace
tr'
        Any -> Any
_ <- (Any -> Any) -> m (Any -> Any)
forall (m :: * -> *) a. MonadEvaluate m => a -> m a
evaluate (Bool -> Any -> Any
forall a. HasCallStack => Bool -> a -> a
assert Bool
False)
        () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

      -- trace transition
      case (OperationResult
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
result, Maybe (PruneAction m)
pruneTr) of
        (OperationSuccess Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr, Maybe (PruneAction m)
Nothing) -> do
          Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr)
          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

        (OperationSuccess Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr, Just PruneAction m
prune) -> do
          Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr)
          PruneAction m -> m ()
forall (m :: * -> *). PruneAction m -> m ()
runPruneAction PruneAction m
prune
          StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar

        (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (PruneAction m))
_ -> () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (MaybeUnknown
   (ConnectionState peerAddr handle handleError version m)
 -> AbstractState)
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> AbstractState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. Transition' state -> state
fromState (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> AbstractState)
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> OperationResult AbstractState
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OperationResult
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
result)


    demotedToColdRemoteImpl
        :: StrictTMVar m (ConnectionManagerState peerAddr handle handleError version m)
        -> peerAddr
        -> m (OperationResult AbstractState)
    demotedToColdRemoteImpl :: StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> peerAddr -> m (OperationResult AbstractState)
demotedToColdRemoteImpl StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar peerAddr
peerAddr = do
      (OperationResult
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
result, Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion) <- STM
  m
  (OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m))),
   Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (STM
   m
   (OperationResult
      (Transition'
         (MaybeUnknown
            (ConnectionState peerAddr handle handleError version m))),
    Maybe (ConnectionManagerTrace peerAddr handlerTrace))
 -> m (OperationResult
         (Transition'
            (MaybeUnknown
               (ConnectionState peerAddr handle handleError version m))),
       Maybe (ConnectionManagerTrace peerAddr handlerTrace)))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> m (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall a b. (a -> b) -> a -> b
$ do
        Maybe (MutableConnState peerAddr handle handleError version m)
mbConnVar <- peerAddr
-> ConnectionManagerState peerAddr handle handleError version m
-> Maybe (MutableConnState peerAddr handle handleError version m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup peerAddr
peerAddr (ConnectionManagerState peerAddr handle handleError version m
 -> Maybe (MutableConnState peerAddr handle handleError version m))
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (Maybe (MutableConnState peerAddr handle handleError version m))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> STM
     m (ConnectionManagerState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
readTMVar StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
        case Maybe (MutableConnState peerAddr handle handleError version m)
mbConnVar of
          Maybe (MutableConnState peerAddr handle handleError version m)
Nothing -> (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return (AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
UnknownConnectionSt
                            , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                            )
          Just MutableConnState { StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar :: forall peerAddr handle handleError version (m :: * -> *).
MutableConnState peerAddr handle handleError version m
-> StrictTVar
     m (ConnectionState peerAddr handle handleError version m)
connVar } -> do
            ConnectionState peerAddr handle handleError version m
connState <- StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> STM m (ConnectionState peerAddr handle handleError version m)
forall (m :: * -> *) a. MonadSTM m => StrictTVar m a -> STM m a
readTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar
            let st :: AbstractState
st = MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (ConnectionState peerAddr handle handleError version m
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. state -> MaybeUnknown state
Known ConnectionState peerAddr handle handleError version m
connState)
            case ConnectionState peerAddr handle handleError version m
connState of
              ReservedOutboundState {} -> do
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
DemotedToColdRemote
                                  Maybe (ConnectionId peerAddr)
forall a. Maybe a
Nothing
                                  AbstractState
st)
                              )
                       )
              UnnegotiatedState Provenance
_ ConnectionId peerAddr
connId Async m ()
_ ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
DemotedToColdRemote
                                  (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                  AbstractState
st)
                              )
                       )
              OutboundUniState ConnectionId peerAddr
connId Async m ()
_connThread handle
_handle ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
UnsupportedState AbstractState
st
                       , ConnectionManagerTrace peerAddr handlerTrace
-> Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. a -> Maybe a
Just (AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
forall peerAddr handlerTrace.
AssertionLocation peerAddr
-> ConnectionManagerTrace peerAddr handlerTrace
CM.TrUnexpectedlyFalseAssertion
                                (Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
forall peerAddr.
Maybe (ConnectionId peerAddr)
-> AbstractState -> AssertionLocation peerAddr
DemotedToColdRemote
                                  (ConnectionId peerAddr -> Maybe (ConnectionId peerAddr)
forall a. a -> Maybe a
Just ConnectionId peerAddr
connId)
                                  AbstractState
st)
                              )
                       )
              OutboundDupState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle TimeoutExpired
_expired ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState)
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              -- one can only enter 'OutboundIdleState' if remote state is
              -- already cold.
              OutboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
_dataFlow ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState)
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              InboundIdleState ConnectionId peerAddr
_connId Async m ()
_connThread handle
_handle DataFlow
_dataFlow ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState)
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              -- @
              --   DemotedToCold^{dataFlow}_{Remote}
              --     : InboundState dataFlow
              --     → InboundIdleState^\tau dataFlow
              -- @
              InboundState ConnectionId peerAddr
connId Async m ()
connThread handle
handle DataFlow
dataFlow -> do
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> DataFlow
-> ConnectionState peerAddr handle handleError version m
InboundIdleState ConnectionId peerAddr
connId Async m ()
connThread handle
handle DataFlow
dataFlow
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              -- @
              --   DemotedToCold^{dataFlow}_{Remote}
              --     : DuplexState
              --     → OutboundState^\tau Duplex
              -- @
              DuplexState ConnectionId peerAddr
connId Async m ()
connThread handle
handle -> do
                let connState' :: ConnectionState peerAddr handle handleError version m
connState' = ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
forall peerAddr handle handleError version (m :: * -> *).
ConnectionId peerAddr
-> Async m ()
-> handle
-> TimeoutExpired
-> ConnectionState peerAddr handle handleError version m
OutboundDupState ConnectionId peerAddr
connId Async m ()
connThread handle
handle TimeoutExpired
Ticking
                StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
-> ConnectionState peerAddr handle handleError version m
-> STM m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
StrictTVar m a -> a -> STM m ()
writeTVar StrictTVar
  m (ConnectionState peerAddr handle handleError version m)
connVar ConnectionState peerAddr handle handleError version m
connState'
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. a -> OperationResult a
OperationSuccess (ConnectionState peerAddr handle handleError version m
-> ConnectionState peerAddr handle handleError version m
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
forall state. state -> state -> Transition state
mkTransition ConnectionState peerAddr handle handleError version m
connState ConnectionState peerAddr handle handleError version m
connState')
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

              TerminatingState {} ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
TerminatedConnection AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )
              TerminatedState {} ->
                (OperationResult
   (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))),
 Maybe (ConnectionManagerTrace peerAddr handlerTrace))
-> STM
     m
     (OperationResult
        (Transition'
           (MaybeUnknown
              (ConnectionState peerAddr handle handleError version m))),
      Maybe (ConnectionManagerTrace peerAddr handlerTrace))
forall (m :: * -> *) a. Monad m => a -> m a
return ( AbstractState
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
forall a. AbstractState -> OperationResult a
TerminatedConnection AbstractState
st
                       , Maybe (ConnectionManagerTrace peerAddr handlerTrace)
forall a. Maybe a
Nothing
                       )

      Maybe (ConnectionManagerTrace peerAddr handlerTrace)
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall (m :: * -> *) a.
Applicative m =>
Maybe a -> (a -> m ()) -> m ()
whenJust Maybe (ConnectionManagerTrace peerAddr handlerTrace)
mbAssertion ((ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ())
-> (ConnectionManagerTrace peerAddr handlerTrace -> m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ \ConnectionManagerTrace peerAddr handlerTrace
tr' -> do
        Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
-> ConnectionManagerTrace peerAddr handlerTrace -> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer m (ConnectionManagerTrace peerAddr handlerTrace)
tracer ConnectionManagerTrace peerAddr handlerTrace
tr'
        Any -> Any
_ <- (Any -> Any) -> m (Any -> Any)
forall (m :: * -> *) a. MonadEvaluate m => a -> m a
evaluate (Bool -> Any -> Any
forall a. HasCallStack => Bool -> a -> a
assert Bool
False)
        () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

      -- trace transition
      case OperationResult
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
result of
        OperationSuccess Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr ->
          Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
-> m ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer
  m
  (TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m))
trTracer (peerAddr
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> TransitionTrace
     peerAddr (ConnectionState peerAddr handle handleError version m)
forall peerAddr state.
peerAddr -> Transition' state -> TransitionTrace' peerAddr state
TransitionTrace peerAddr
peerAddr Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
tr)
        OperationResult
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
_ -> () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

      StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
-> m ()
traceCounters StrictTMVar
  m (ConnectionManagerState peerAddr handle handleError version m)
stateVar
      OperationResult AbstractState -> m (OperationResult AbstractState)
forall (m :: * -> *) a. Monad m => a -> m a
return (MaybeUnknown
  (ConnectionState peerAddr handle handleError version m)
-> AbstractState
forall muxMode peerAddr m a (b :: * -> *).
MaybeUnknown (ConnectionState muxMode peerAddr m a b)
-> AbstractState
abstractState (MaybeUnknown
   (ConnectionState peerAddr handle handleError version m)
 -> AbstractState)
-> (Transition'
      (MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
    -> MaybeUnknown
         (ConnectionState peerAddr handle handleError version m))
-> Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m))
-> AbstractState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transition'
  (MaybeUnknown
     (ConnectionState peerAddr handle handleError version m))
-> MaybeUnknown
     (ConnectionState peerAddr handle handleError version m)
forall state. Transition' state -> state
fromState (Transition'
   (MaybeUnknown
      (ConnectionState peerAddr handle handleError version m))
 -> AbstractState)
-> OperationResult
     (Transition'
        (MaybeUnknown
           (ConnectionState peerAddr handle handleError version m)))
-> OperationResult AbstractState
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OperationResult
  (Transition'
     (MaybeUnknown
        (ConnectionState peerAddr handle handleError version m)))
result)


--
-- Utilities
--

-- | Perform some operation on 'Just', given the field inside the 'Just'.
--
whenJust :: Applicative m => Maybe a -> (a -> m ()) -> m ()
whenJust :: Maybe a -> (a -> m ()) -> m ()
whenJust Maybe a
mg a -> m ()
f = m () -> (a -> m ()) -> Maybe a -> m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) a -> m ()
f Maybe a
mg

-- | Like 'modifyMVar' but strict in @a@ and for 'TMVar's
--
modifyTMVar :: ( MonadEvaluate m
               , MonadMask     m
               , MonadSTM      m
               )
            => StrictTMVar m a
            -> (a -> m (a, b))
            -> m b
modifyTMVar :: StrictTMVar m a -> (a -> m (a, b)) -> m b
modifyTMVar StrictTMVar m a
v a -> m (a, b)
k =
  ((forall a. m a -> m a) -> m b) -> m b
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m b) -> m b)
-> ((forall a. m a -> m a) -> m b) -> m b
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
restore -> do
    a
a <- STM m a -> m a
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (StrictTMVar m a -> STM m a
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
takeTMVar StrictTMVar m a
v)
    (a
a',b
b) <- m (a, b) -> m (a, b)
forall a. m a -> m a
restore (a -> m (a, b)
k a
a m (a, b) -> ((a, b) -> m (a, b)) -> m (a, b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a, b) -> m (a, b)
forall (m :: * -> *) a. MonadEvaluate m => a -> m a
evaluate)
      m (a, b) -> m () -> m (a, b)
forall (m :: * -> *) a b. MonadCatch m => m a -> m b -> m a
`onException`
        STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (StrictTMVar m a -> a -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTMVar m a -> a -> STM m ()
putTMVar StrictTMVar m a
v a
a)
    STM m () -> m ()
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
STM m a -> m a
atomically (StrictTMVar m a -> a -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTMVar m a -> a -> STM m ()
putTMVar StrictTMVar m a
v a
a')
    b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
b

modifyTMVarSTM :: MonadSTM m => StrictTMVar m a -> (a -> STM m (a, b)) -> STM m b
modifyTMVarSTM :: StrictTMVar m a -> (a -> STM m (a, b)) -> STM m b
modifyTMVarSTM StrictTMVar m a
v a -> STM m (a, b)
k = do
    a
a <- StrictTMVar m a -> STM m a
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
takeTMVar StrictTMVar m a
v
    (a
a',b
b) <- a -> STM m (a, b)
k a
a
    StrictTMVar m a -> a -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTMVar m a -> a -> STM m ()
putTMVar StrictTMVar m a
v a
a'
    b -> STM m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
b

-- | Like 'modifyMVar' but pure.
--
modifyTMVarPure :: MonadSTM m
                => StrictTMVar m a
                -> (a -> (a, b))
                -> STM m b
modifyTMVarPure :: StrictTMVar m a -> (a -> (a, b)) -> STM m b
modifyTMVarPure StrictTMVar m a
v a -> (a, b)
k = do
    a
a <- StrictTMVar m a -> STM m a
forall (m :: * -> *) a. MonadSTM m => StrictTMVar m a -> STM m a
takeTMVar StrictTMVar m a
v
    let (a
a', b
b) = a -> (a, b)
k a
a
    StrictTMVar m a -> a -> STM m ()
forall (m :: * -> *) a.
MonadSTM m =>
StrictTMVar m a -> a -> STM m ()
putTMVar StrictTMVar m a
v a
a'
    b -> STM m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
b

--
-- Exceptions
--

-- | Useful to attach 'CallStack' to 'ConnectionManagerError'.
--
withCallStack :: HasCallStack => (CallStack -> a) -> a
withCallStack :: (CallStack -> a) -> a
withCallStack CallStack -> a
k = CallStack -> a
k CallStack
HasCallStack => CallStack
callStack