ouroboros-consensus-0.18.0.0: Consensus layer for the Ouroboros blockchain protocol
Safe HaskellSafe-Inferred
LanguageHaskell2010

Ouroboros.Consensus.Util.MonadSTM.StrictSVar

Synopsis

Documentation

castStrictSVar ∷ (TMVar m ~ TMVar n, TVar m ~ TVar n) ⇒ StrictSVar m a → StrictSVar n a Source #

modifySVar ∷ (MonadSTM m, MonadCatch m, HasCallStack) ⇒ StrictSVar m a → (a → m (a, b)) → m b Source #

modifySVar_ ∷ (MonadSTM m, MonadCatch m, HasCallStack) ⇒ StrictSVar m a → (a → m a) → m () Source #

newEmptySVarMonadSTM m ⇒ a → m (StrictSVar m a) Source #

newEmptySVarWithInvariant Source #

Arguments

MonadSTM m 
⇒ (a → Maybe String)

Invariant (expect Nothing)

→ a

The initial stale value

→ m (StrictSVar m a) 

Create an initially empty StrictSVar

NOTE: Since readSVarSTM allows to read the StrictSVar even when it is empty, we need an initial value of a even though the StrictSVar starts out empty. However, we are NOT strict in this value, to allow it to be error.

newSVarMonadSTM m ⇒ a → m (StrictSVar m a) Source #

newSVarWithInvariant Source #

Arguments

∷ (MonadSTM m, HasCallStack) 
⇒ (a → Maybe String)

Invariant (expect Nothing)

→ a 
→ m (StrictSVar m a) 

putSVar ∷ (MonadSTM m, HasCallStack) ⇒ StrictSVar m a → a → m () Source #

readSVarMonadSTM m ⇒ StrictSVar m a → m a Source #

readSVarSTMMonadSTM m ⇒ StrictSVar m a → STM m a Source #

Read the possibly-stale value of the SVar

Will return the current value of the SVar if it non-empty, or the last known value otherwise.

swapSVar ∷ (MonadSTM m, HasCallStack) ⇒ StrictSVar m a → a → m a Source #

Swap value of a StrictSVar

NOTE: Since swapping the value can't leave the StrictSVar empty, we could check the invariant first and only then swap. We nonetheless swap first and check the invariant after to keep the semantics the same with putSVar, otherwise it will be difficult to understand when a StrictSVar is updated and when it is not.

takeSVarMonadSTM m ⇒ StrictSVar m a → m a Source #

tryPutSVar ∷ (MonadSTM m, HasCallStack) ⇒ StrictSVar m a → a → m Bool Source #

tryReadSVarMonadSTM m ⇒ StrictSVar m a → m (Maybe a) Source #

tryTakeSVarMonadSTM m ⇒ StrictSVar m a → m (Maybe a) Source #

updateSVar ∷ (MonadSTM m, HasCallStack) ⇒ StrictSVar m a → (a → (a, b)) → m b Source #

updateSVar_ ∷ (MonadSTM m, HasCallStack) ⇒ StrictSVar m a → (a → a) → m () Source #

constructors exported for benefit of tests

data StrictSVar m a Source #

Strict SVar (modelled using a lazy TMVar under the hood)

The StrictSVar API is slightly stronger than the usual SVar one, as we offer a primitive to read the value of the SVar even if it is empty (in which case we will return the oldest known stale one). See readSVarSTM.

There is a weaker invariant for a StrictSVar than for a StrictTVar: although all functions that modify the StrictSVar check the invariant, we do not guarantee that the value inside the StrictSVar always satisfies the invariant. Instead, we do guarantee that if the StrictSVar is updated with a value that does not satisfy the invariant, an exception is thrown. The reason for this weaker guarantee is that leaving an SVar empty can lead to very hard to debug "blocked indefinitely" problems.

This is also the reason we do not offer support for an invariant in StrictTMVar: if we throw an exception from an STM transaction, the STM transaction is not executed, and so we would not even be able to provide the weaker guarantee that we provide for StrictSVar.

Constructors

StrictSVar 

Fields

  • invariant ∷ !(a → Maybe String)

    Invariant checked whenever updating the StrictSVar.

  • tmvar ∷ !(TMVar m a)

    The main TMVar supporting this StrictSVar

  • tvar ∷ !(TVar m a)

    TVar for supporting readSVarSTM

    This TVar is always kept up to date with the TMVar, but holds on the old value of the TMVar when it is empty. This is very useful to support single writer/many reader scenarios.

    NOTE: We should always update the tmvar before the tvar so that if the update to the tmvar fails, the 'tvar is left unchanged.