Copyright | (c) Oleksandr Zhabenko |
---|---|
License | MIT |
Maintainer | oleksandr.zhabenko@yahoo.com |
Stability | experimental |
Portability | POSIX |
Safe Haskell | None |
Language | Haskell2010 |
Keter.RateLimiter.Types
Description
This module provides the fundamental data types used in Keter's rate limiting system. It defines state representations for two common rate limiting algorithms:
- Token Bucket: A rate limiting algorithm that maintains a bucket of tokens, where each request consumes a token. Tokens are replenished at a fixed rate.
- Leaky Bucket: A rate limiting algorithm that models a bucket with a hole, where requests fill the bucket and it drains at a constant rate.
Both types support JSON serialization for persistence and configuration purposes, with validation to ensure state consistency.
Example Usage
-- Token bucket example let tokenState = TokenBucketState { tokens = 100, lastUpdate = 1640995200 } print tokenState -- TokenBucketState {tokens = 100, lastUpdate = 1640995200} -- Leaky bucket example let leakyState = LeakyBucketState { level = 0.5, lastTime = 1640995200.123 } print leakyState -- LeakyBucketState {level = 0.5, lastTime = 1640995200.123}
Synopsis
- data TokenBucketState = TokenBucketState {
- tokens :: Int
- lastUpdate :: Int
- data LeakyBucketState = LeakyBucketState {}
Token Bucket Algorithm
data TokenBucketState Source #
State representation for the Token Bucket rate limiting algorithm.
The token bucket algorithm maintains a bucket that holds tokens up to a maximum capacity. Each incoming request consumes one or more tokens from the bucket. Tokens are replenished at a fixed rate. If insufficient tokens are available, the request is either delayed or rejected.
Token Bucket Properties
- Bursty Traffic: Allows bursts of traffic up to the bucket capacity
- Rate Control: Long-term average rate is controlled by token replenishment rate
- Memory Efficient: Only requires tracking token count and last update time
Use Cases
- API rate limiting with burst allowance
- Network traffic shaping
- Resource allocation with temporary overages
Example
-- Initial state with 50 tokens, last updated at Unix timestamp 1640995200 let initialState = TokenBucketState { tokens = 50 , lastUpdate = 1640995200 } -- After consuming 10 tokens let afterConsumption = initialState { tokens = 40 }
Constructors
TokenBucketState | |
Fields
|
Instances
FromJSON TokenBucketState Source # |
Deserializes JSON to
Validation Examples-- Valid JSON decode "{"tokens": 10, "lastUpdate": 1640995200}" :: Maybe TokenBucketState -- Just (TokenBucketState {tokens = 10, lastUpdate = 1640995200}) -- Invalid JSON (negative tokens) decode "{"tokens": -5, "lastUpdate": 1640995200}" :: Maybe TokenBucketState -- Nothing Throws a parse error if | ||||
Defined in Keter.RateLimiter.Types Methods parseJSON :: Value -> Parser TokenBucketState # parseJSONList :: Value -> Parser [TokenBucketState] # | |||||
ToJSON TokenBucketState Source # |
Serializes the token bucket state to JSON format for persistence or network transmission. JSON Format{ "tokens": 42, "lastUpdate": 1640995200 } | ||||
Defined in Keter.RateLimiter.Types Methods toJSON :: TokenBucketState -> Value # toEncoding :: TokenBucketState -> Encoding # toJSONList :: [TokenBucketState] -> Value # toEncodingList :: [TokenBucketState] -> Encoding # omitField :: TokenBucketState -> Bool # | |||||
Generic TokenBucketState Source # | |||||
Defined in Keter.RateLimiter.Types Associated Types
Methods from :: TokenBucketState -> Rep TokenBucketState x # to :: Rep TokenBucketState x -> TokenBucketState # | |||||
Show TokenBucketState Source # | |||||
Defined in Keter.RateLimiter.Types Methods showsPrec :: Int -> TokenBucketState -> ShowS # show :: TokenBucketState -> String # showList :: [TokenBucketState] -> ShowS # | |||||
Eq TokenBucketState Source # | |||||
Defined in Keter.RateLimiter.Types Methods (==) :: TokenBucketState -> TokenBucketState -> Bool # (/=) :: TokenBucketState -> TokenBucketState -> Bool # | |||||
CacheStore (InMemoryStore 'TokenBucket) TokenBucketState IO Source # | CacheStore instance for TokenBucket algorithm. Provides access to token bucket state while maintaining the worker thread infrastructure. Read operations return current bucket state, write operations update state and manage worker lifecycle. | ||||
Defined in Keter.RateLimiter.Cache Methods readStore :: InMemoryStore 'TokenBucket -> Text -> Text -> IO (Maybe TokenBucketState) Source # writeStore :: InMemoryStore 'TokenBucket -> Text -> Text -> TokenBucketState -> Int -> IO () Source # deleteStore :: InMemoryStore 'TokenBucket -> Text -> Text -> IO () Source # incStore :: InMemoryStore 'TokenBucket -> Text -> Text -> Int -> IO TokenBucketState Source # | |||||
type Rep TokenBucketState Source # | |||||
Defined in Keter.RateLimiter.Types type Rep TokenBucketState = D1 ('MetaData "TokenBucketState" "Keter.RateLimiter.Types" "keter-rate-limiting-plugin-0.2.0.0-H4WU5a5Xu20FyQxdNRgnJy" 'False) (C1 ('MetaCons "TokenBucketState" 'PrefixI 'True) (S1 ('MetaSel ('Just "tokens") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int) :*: S1 ('MetaSel ('Just "lastUpdate") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int))) |
Leaky Bucket Algorithm
data LeakyBucketState Source #
State representation for the Leaky Bucket rate limiting algorithm.
The leaky bucket algorithm models a bucket with a hole in the bottom that drains at a constant rate. Incoming requests add water to the bucket, and if the bucket overflows, requests are rejected. This provides smooth rate limiting without bursts.
Leaky Bucket Properties
- Smooth Rate: Enforces a consistent output rate regardless of input bursts
- No Bursts: Unlike token bucket, doesn't allow temporary rate exceedance
- Queue Modeling: Can model request queuing with bucket level representing queue depth
Use Cases
- Smooth traffic shaping for network connections
- Audio/video streaming rate control
- Database connection throttling
- Prevention of thundering herd problems
Mathematical Model
The bucket level changes according to:
newLevel = max(0, oldLevel + requestSize - drainRate * timeDelta)
Where:
requestSize
is the size of the incoming requestdrainRate
is the constant drain rate (requests per second)timeDelta
is the elapsed time since last update
Example
-- Initial state: half-full bucket at timestamp 1640995200.5 let initialState = LeakyBucketState { level = 0.5 , lastTime = 1640995200.5 } -- After 1 second with drain rate 0.1/sec and no new requests let afterDrain = initialState { level = 0.4 -- 0.5 - 0.1*1.0 , lastTime = 1640995201.5 }
Constructors
LeakyBucketState | |
Fields
|
Instances
FromJSON LeakyBucketState Source # |
Deserializes JSON to
The upper bound on Validation Examples-- Valid JSON decode "{"level": 42.5, "lastTime": 1640995200.123}" :: Maybe LeakyBucketState -- Just (LeakyBucketState {level = 42.5, lastTime = 1640995200.123}) -- Invalid JSON (negative level) decode "{"level": -1.0, "lastTime": 1640995200.0}" :: Maybe LeakyBucketState -- Nothing -- Invalid JSON (level too high) decode "{"level": 2000000.0, "lastTime": 1640995200.0}" :: Maybe LeakyBucketState -- Nothing Throws a parse error if | ||||
Defined in Keter.RateLimiter.Types Methods parseJSON :: Value -> Parser LeakyBucketState # parseJSONList :: Value -> Parser [LeakyBucketState] # | |||||
ToJSON LeakyBucketState Source # |
Serializes the leaky bucket state to JSON format with full double precision. JSON Format{ "level": 123.456, "lastTime": 1640995200.789 } | ||||
Defined in Keter.RateLimiter.Types Methods toJSON :: LeakyBucketState -> Value # toEncoding :: LeakyBucketState -> Encoding # toJSONList :: [LeakyBucketState] -> Value # toEncodingList :: [LeakyBucketState] -> Encoding # omitField :: LeakyBucketState -> Bool # | |||||
Generic LeakyBucketState Source # | |||||
Defined in Keter.RateLimiter.Types Associated Types
Methods from :: LeakyBucketState -> Rep LeakyBucketState x # to :: Rep LeakyBucketState x -> LeakyBucketState # | |||||
Show LeakyBucketState Source # | |||||
Defined in Keter.RateLimiter.Types Methods showsPrec :: Int -> LeakyBucketState -> ShowS # show :: LeakyBucketState -> String # showList :: [LeakyBucketState] -> ShowS # | |||||
Eq LeakyBucketState Source # | |||||
Defined in Keter.RateLimiter.Types Methods (==) :: LeakyBucketState -> LeakyBucketState -> Bool # (/=) :: LeakyBucketState -> LeakyBucketState -> Bool # | |||||
CacheStore (InMemoryStore 'LeakyBucket) LeakyBucketState IO Source # | CacheStore instance for LeakyBucket algorithm. Similar to TokenBucket but for continuous drain semantics. Manages leaky bucket state and worker thread lifecycle. | ||||
Defined in Keter.RateLimiter.Cache Methods readStore :: InMemoryStore 'LeakyBucket -> Text -> Text -> IO (Maybe LeakyBucketState) Source # writeStore :: InMemoryStore 'LeakyBucket -> Text -> Text -> LeakyBucketState -> Int -> IO () Source # deleteStore :: InMemoryStore 'LeakyBucket -> Text -> Text -> IO () Source # incStore :: InMemoryStore 'LeakyBucket -> Text -> Text -> Int -> IO LeakyBucketState Source # | |||||
type Rep LeakyBucketState Source # | |||||
Defined in Keter.RateLimiter.Types type Rep LeakyBucketState = D1 ('MetaData "LeakyBucketState" "Keter.RateLimiter.Types" "keter-rate-limiting-plugin-0.2.0.0-H4WU5a5Xu20FyQxdNRgnJy" 'False) (C1 ('MetaCons "LeakyBucketState" 'PrefixI 'True) (S1 ('MetaSel ('Just "level") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Double) :*: S1 ('MetaSel ('Just "lastTime") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Double))) |