LootLocker Unreal SDK 10.4.0
Game backend SDK for Unreal Engine
Loading...
Searching...
No Matches
FLootLockerRateLimiter Class Reference

Client-side rate limiter for the LootLocker HTTP execution queue. More...

#include <LootLockerRateLimiter.h>

Public Member Functions

 FLootLockerRateLimiter ()
 
virtual ~FLootLockerRateLimiter ()=default
 
void Reset ()
 Resets all rate-limiting state to its initial values.
 
virtual bool AddRequestAndCheckIfRateLimitHit ()
 Records one outgoing request and returns whether the rate limit is currently active.
 
int32 GetSecondsLeftOfRateLimit () const
 Returns the approximate number of seconds until the rate limit clears.
 

Static Public Attributes

static constexpr int32 TripWireTimeFrameSeconds = 60
 Length of the tripwire measurement window in seconds.
 
static constexpr int32 MaxRequestsPerTripWireTimeFrame = 280
 Maximum requests allowed within a single TripWireTimeFrameSeconds window.
 
static constexpr int32 SecondsPerBucket = 5
 Duration of each bucket in seconds.
 
static constexpr float AllowXPercentOfTripWireMaxForMovingAverage = 0.8f
 Moving-average threshold expressed as a fraction of the tripwire maximum.
 
static constexpr int32 CountMovingAverageAcrossNTripWireTimeFrames = 3
 Number of tripwire time frames covered by the moving-average window.
 
static constexpr int32 BucketsPerTimeFrame = TripWireTimeFrameSeconds / SecondsPerBucket
 Number of buckets that span one tripwire time frame (= 60 / 5 = 12).
 
static constexpr int32 RateLimitMovingAverageBucketCount = CountMovingAverageAcrossNTripWireTimeFrames * BucketsPerTimeFrame
 Total number of buckets in the circular array (= 3 * 12 = 36).
 
static constexpr int32 MaxRequestsPerBucketOnMovingAverage
 Per-bucket average that triggers the moving-average rate limit.
 

Protected Member Functions

virtual FDateTime GetTimeNow () const
 Returns the current wall-clock time used for bucket advancement.
 

Protected Attributes

bool bEnableRateLimiter = true
 When false, AddRequestAndCheckIfRateLimitHit() always returns false.
 
bool bFirstRequestSent = false
 Set to true once the first request has been processed.
 
int32 Buckets [RateLimitMovingAverageBucketCount]
 Circular array of per-bucket request counts.
 
int32 LastBucket = -1
 Index of the most-recently-written bucket (-1 = not yet started).
 
FDateTime LastBucketChangeTime
 Wall-clock time at which the current bucket became active.
 
int32 TotalRequestsInBuckets = 0
 Running total of all requests across every bucket in the array.
 
int32 TotalRequestsInBucketsInTripWireTimeFrame = 0
 Running total of requests in the buckets that fall within the current tripwire time frame.
 
bool bIsRateLimited = false
 True while requests are being rejected due to an active rate limit.
 
FDateTime RateLimitResolvesAt
 Wall-clock time at which the current rate limit is expected to clear.
 

Detailed Description

Client-side rate limiter for the LootLocker HTTP execution queue.

Uses a dual-threshold sliding-window algorithm (ported from the Unity SDK) to detect both sudden large bursts and sustained high-frequency request patterns before they reach the server:

Tripwire — hard cap: more than MaxRequestsPerTripWireTimeFrame (280) requests within any rolling TripWireTimeFrameSeconds (60 s) window.

Moving average — soft cap: the average requests-per-bucket across the full RateLimitMovingAverageBucketCount (36) buckets exceeds MaxRequestsPerBucketOnMovingAverage (18), i.e. sustained traffic at > 80 % of the tripwire rate over the past 3 minutes.

Both thresholds are tracked via a circular array of int32 buckets, each covering SecondsPerBucket (5) seconds. Time-advancement is virtual so unit tests can drive the clock without real sleeps.

Usage: FLootLockerRateLimiter Limiter; if (Limiter.AddRequestAndCheckIfRateLimitHit()) { ... deny or queue ... }

Constructor & Destructor Documentation

◆ FLootLockerRateLimiter()

FLootLockerRateLimiter::FLootLockerRateLimiter ( )

◆ ~FLootLockerRateLimiter()

virtual FLootLockerRateLimiter::~FLootLockerRateLimiter ( )
virtualdefault

Member Function Documentation

◆ AddRequestAndCheckIfRateLimitHit()

virtual bool FLootLockerRateLimiter::AddRequestAndCheckIfRateLimitHit ( )
virtual

Records one outgoing request and returns whether the rate limit is currently active.

Returns
true if the caller should back off (rate limit is active). false if the request may proceed normally.

◆ GetSecondsLeftOfRateLimit()

int32 FLootLockerRateLimiter::GetSecondsLeftOfRateLimit ( ) const

Returns the approximate number of seconds until the rate limit clears.

Returns 0 when no rate limit is active.

◆ GetTimeNow()

virtual FDateTime FLootLockerRateLimiter::GetTimeNow ( ) const
protectedvirtual

Returns the current wall-clock time used for bucket advancement.

Override in test subclasses to control time deterministically.

◆ Reset()

void FLootLockerRateLimiter::Reset ( )

Resets all rate-limiting state to its initial values.

Call this when the SDK session is torn down, or for unit-test isolation.

Field Documentation

◆ AllowXPercentOfTripWireMaxForMovingAverage

constexpr float FLootLockerRateLimiter::AllowXPercentOfTripWireMaxForMovingAverage = 0.8f
staticconstexpr

Moving-average threshold expressed as a fraction of the tripwire maximum.

The per-bucket average across CountMovingAverageAcrossNTripWireTimeFrames windows must stay at or below this percentage.

◆ bEnableRateLimiter

bool FLootLockerRateLimiter::bEnableRateLimiter = true
protected

When false, AddRequestAndCheckIfRateLimitHit() always returns false.

◆ bFirstRequestSent

bool FLootLockerRateLimiter::bFirstRequestSent = false
protected

Set to true once the first request has been processed.

Used to defer the production-environment check until the SDK is running.

◆ bIsRateLimited

bool FLootLockerRateLimiter::bIsRateLimited = false
protected

True while requests are being rejected due to an active rate limit.

◆ Buckets

int32 FLootLockerRateLimiter::Buckets[RateLimitMovingAverageBucketCount]
protected

Circular array of per-bucket request counts.

◆ BucketsPerTimeFrame

constexpr int32 FLootLockerRateLimiter::BucketsPerTimeFrame = TripWireTimeFrameSeconds / SecondsPerBucket
staticconstexpr

Number of buckets that span one tripwire time frame (= 60 / 5 = 12).

◆ CountMovingAverageAcrossNTripWireTimeFrames

constexpr int32 FLootLockerRateLimiter::CountMovingAverageAcrossNTripWireTimeFrames = 3
staticconstexpr

Number of tripwire time frames covered by the moving-average window.

◆ LastBucket

int32 FLootLockerRateLimiter::LastBucket = -1
protected

Index of the most-recently-written bucket (-1 = not yet started).

◆ LastBucketChangeTime

FDateTime FLootLockerRateLimiter::LastBucketChangeTime
protected

Wall-clock time at which the current bucket became active.

◆ MaxRequestsPerBucketOnMovingAverage

constexpr int32 FLootLockerRateLimiter::MaxRequestsPerBucketOnMovingAverage
staticconstexpr
Initial value:
=
static constexpr int32 BucketsPerTimeFrame
Number of buckets that span one tripwire time frame (= 60 / 5 = 12).
Definition LootLockerRateLimiter.h:61
static constexpr int32 MaxRequestsPerTripWireTimeFrame
Maximum requests allowed within a single TripWireTimeFrameSeconds window.
Definition LootLockerRateLimiter.h:41

Per-bucket average that triggers the moving-average rate limit.

= (280 * 0.8) / 12 = 18 (computed as (280 * 4) / (12 * 5) to avoid float constexpr).

◆ MaxRequestsPerTripWireTimeFrame

constexpr int32 FLootLockerRateLimiter::MaxRequestsPerTripWireTimeFrame = 280
staticconstexpr

Maximum requests allowed within a single TripWireTimeFrameSeconds window.

◆ RateLimitMovingAverageBucketCount

constexpr int32 FLootLockerRateLimiter::RateLimitMovingAverageBucketCount = CountMovingAverageAcrossNTripWireTimeFrames * BucketsPerTimeFrame
staticconstexpr

Total number of buckets in the circular array (= 3 * 12 = 36).

◆ RateLimitResolvesAt

FDateTime FLootLockerRateLimiter::RateLimitResolvesAt
protected

Wall-clock time at which the current rate limit is expected to clear.

◆ SecondsPerBucket

constexpr int32 FLootLockerRateLimiter::SecondsPerBucket = 5
staticconstexpr

Duration of each bucket in seconds.

Must evenly divide TripWireTimeFrameSeconds.

◆ TotalRequestsInBuckets

int32 FLootLockerRateLimiter::TotalRequestsInBuckets = 0
protected

Running total of all requests across every bucket in the array.

◆ TotalRequestsInBucketsInTripWireTimeFrame

int32 FLootLockerRateLimiter::TotalRequestsInBucketsInTripWireTimeFrame = 0
protected

Running total of requests in the buckets that fall within the current tripwire time frame.

◆ TripWireTimeFrameSeconds

constexpr int32 FLootLockerRateLimiter::TripWireTimeFrameSeconds = 60
staticconstexpr

Length of the tripwire measurement window in seconds.