Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
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
- data Config m = Config {}
- data Handlers m = Handlers {}
- data State m = State {}
- atomicallyWithMonotonicTime ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ (Time → STM m b) → m b
- diffTimeToSecondsRational ∷ DiffTime → Rational
- dummyConfig ∷ Applicative m ⇒ Config m
- evalAgainstBucket ∷ (MonadDelay m, MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, NoThunks (m ())) ⇒ Config m → (Handlers m → m a) → m (State m)
- execAgainstBucket ∷ (MonadDelay m, MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, NoThunks (m ())) ⇒ Config m → (Handlers m → m a) → m a
- execAgainstBucket' ∷ (MonadDelay m, MonadAsync m, MonadFork m, MonadMask m, MonadTimer m, NoThunks (m ())) ⇒ (Handlers m → m a) → m a
- fill' ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ Handlers m → Rational → m FillResult
- microsecondsPerSecond ∷ Integer
- picosecondsPerSecond ∷ Integer
- 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)
- secondsRationalToDiffTime ∷ Rational → DiffTime
- setPaused' ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ Handlers m → Bool → m ()
- updateConfig' ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ Handlers m → ((Rational, Config m) → (Rational, Config m)) → m ()
Documentation
Configuration of a leaky bucket.
Instances
Generic (Config m) Source # | |
NoThunks (m ()) ⇒ NoThunks (Config m) Source # | |
type Rep (Config m) Source # | |
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 ()))))) |
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
.
Handlers | |
|
State of a leaky bucket, giving the level and the associated time.
Instances
Generic (State m) Source # | |
NoThunks (m ()) ⇒ NoThunks (State m) Source # | |
type Rep (State m) Source # | |
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)))))) |
atomicallyWithMonotonicTime ∷ (MonadMonotonicTime m, MonadSTM m) ⇒ (Time → STM m b) → m b Source #
Helper around getMonotonicTime
and atomically
.
dummyConfig ∷ Applicative 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
.
microsecondsPerSecond ∷ Integer Source #
Number of microseconds in a second (10^6
).
picosecondsPerSecond ∷ Integer 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.
secondsRationalToDiffTime ∷ Rational → DiffTime 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
.