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

Ouroboros.Consensus.Util.LeakyBucket

Description

This module implements a “leaky bucket”. One defines a bucket with a capacity and a leaking rate; a race (in the sense of Async) starts against the bucket which leaks at the given rate. The user is provided with a function to refill the bucket by a certain amount. If the bucket ever goes empty, both threads are cancelled.

This can be used for instance to enforce a minimal rate of a peer: they race against the bucket and refill the bucket by a certain amount whenever they do a “good” action.

NOTE: Even though the imagery is the same, this is different from what is usually called a “token bucket” or “leaky bucket” in the litterature where it is mostly used for rate limiting.

REVIEW: Could be used as leaky bucket used for rate limiting algorithms. All the infrastructure is here (put onEmpty to pure () and you're good to go) but it has not been tested with that purpose in mind.

Synopsis

Documentation

data Config m Source #

Configuration of a leaky bucket.

Constructors

Config 

Fields

  • capacity ∷ !Rational

    Initial and maximal capacity of the bucket, in number of tokens.

  • rate ∷ !Rational

    Tokens per second leaking off the bucket.

  • fillOnOverflow ∷ !Bool

    Whether to fill to capacity on overflow or to do nothing.

  • onEmpty ∷ !(m ())

    A monadic action to trigger when the bucket is empty.

Instances

Instances details
Generic (Config m) Source # 
Instance details

Defined in Ouroboros.Consensus.Util.LeakyBucket

Associated Types

type Rep (Config m) ∷ TypeType #

Methods

fromConfig m → Rep (Config m) x #

toRep (Config m) x → Config m #

NoThunks (m ()) ⇒ NoThunks (Config m) Source # 
Instance details

Defined in Ouroboros.Consensus.Util.LeakyBucket

type Rep (Config m) Source # 
Instance details

Defined in Ouroboros.Consensus.Util.LeakyBucket

type Rep (Config m) = D1 ('MetaData "Config" "Ouroboros.Consensus.Util.LeakyBucket" "ouroboros-consensus-0.21.0.0-inplace" 'False) (C1 ('MetaCons "Config" 'PrefixI 'True) ((S1 ('MetaSel ('Just "capacity") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Rational) :*: S1 ('MetaSel ('Just "rate") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Rational)) :*: (S1 ('MetaSel ('Just "fillOnOverflow") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: S1 ('MetaSel ('Just "onEmpty") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (m ())))))

data Handlers m Source #

The handlers to a bucket: contains the API to interact with a running bucket. All the endpoints are STM but require the current time; the easy way to provide this being atomicallyWithMonotonicTime.

Constructors

Handlers 

Fields

  • fill ∷ !(RationalTimeSTM m FillResult)

    Refill the bucket by the given amount and returns whether the bucket overflew. The bucket may silently get filled to full capacity or not get filled depending on fillOnOverflow.

  • setPaused ∷ !(BoolTimeSTM m ())

    Pause or resume the bucket. Pausing stops the bucket from leaking until it is resumed. It is still possible to fill it during that time. setPaused True and setPaused False are idempotent.

  • updateConfig ∷ !(((Rational, Config m) → (Rational, Config m)) → TimeSTM m ())

    Dynamically update the level and configuration of the bucket. Updating the level matters if the capacity changes, in particular. If updating leave the bucket empty, the action is triggered immediately.

data State m Source #

State of a leaky bucket, giving the level and the associated time.

Constructors

State 

Fields

Instances

Instances details
Generic (State m) Source # 
Instance details

Defined in Ouroboros.Consensus.Util.LeakyBucket

Associated Types

type Rep (State m) ∷ TypeType #

Methods

fromState m → Rep (State m) x #

toRep (State m) x → State m #

NoThunks (m ()) ⇒ NoThunks (State m) Source # 
Instance details

Defined in Ouroboros.Consensus.Util.LeakyBucket

type Rep (State m) Source # 
Instance details

Defined in Ouroboros.Consensus.Util.LeakyBucket

type Rep (State m) = D1 ('MetaData "State" "Ouroboros.Consensus.Util.LeakyBucket" "ouroboros-consensus-0.21.0.0-inplace" 'False) (C1 ('MetaCons "State" 'PrefixI 'True) ((S1 ('MetaSel ('Just "level") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Rational) :*: S1 ('MetaSel ('Just "time") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Time)) :*: (S1 ('MetaSel ('Just "paused") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "configGeneration") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Just "config") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Config m))))))

diffTimeToSecondsRationalDiffTimeRational Source #

Convert a DiffTime to a Rational number of seconds. This is similar to diffTimeToSeconds but with picoseconds precision.

dummyConfigApplicative m ⇒ Config m Source #

A configuration for a bucket that does nothing.

evalAgainstBucket ∷ (MonadDelay m, MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, NoThunks (m ())) ⇒ Config m → (Handlers m → m a) → m (State m) Source #

Same as execAgainstBucket but returns the State of the bucket when the action terminates. Exposed for testing purposes.

execAgainstBucket ∷ (MonadDelay m, MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, NoThunks (m ())) ⇒ Config m → (Handlers m → m a) → m a Source #

Create a bucket with the given configuration, then run the action against that bucket. Returns when the action terminates or the bucket empties. In the first case, return the value returned by the action. In the second case, return Nothing.

execAgainstBucket' ∷ (MonadDelay m, MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, NoThunks (m ())) ⇒ (Handlers m → m a) → m a Source #

Variant of execAgainstBucket that uses a dummy configuration. This only makes sense for actions that use updateConfig.

fill' ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ Handlers m → Rational → m FillResult Source #

Variant of fill already wrapped in atomicallyWithMonotonicTime.

microsecondsPerSecondInteger Source #

Number of microseconds in a second (10^6).

picosecondsPerSecondInteger Source #

Number of picoseconds in a second (10^12).

runAgainstBucket ∷ ∀ m a. (MonadDelay m, MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, NoThunks (m ())) ⇒ Config m → (Handlers m → m a) → m (State m, a) Source #

Same as execAgainstBucket but also returns the State of the bucket when the action terminates. Exposed for testing purposes.

secondsRationalToDiffTimeRationalDiffTime Source #

Alias of realToFrac to make code more readable and typing more explicit.

setPaused' ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ Handlers m → Bool → m () Source #

Variant of setPaused already wrapped in atomicallyWithMonotonicTime.

updateConfig' ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ Handlers m → ((Rational, Config m) → (Rational, Config m)) → m () Source #

Variant of updateConfig already wrapped in atomicallyWithMonotonicTime.