[#BloombergLP-balb-RateLimiter]
= xref:BloombergLP.adoc[BloombergLP]::xref:BloombergLP/balb.adoc[balb]::RateLimiter
:relfileprefix: ../../
:mrdocs:

This mechanism implements a rate limiter that allows clients to monitor and control the usage of a resource such that the rate of consumption stays within configured limits&period; The behavior of a rate limiter is determined by four properties&colon; the sustained rate (in units&sol;s), the sustained&hyphen;rate time&hyphen;window (in seconds), the peak rate (in units&sol;s), and the peak&hyphen;rate time&hyphen;window (in seconds)&period; All of these properties can be specified at construction or using the `setRateLimits` method&period;

== Synopsis

Declared in `&lt;balb&lowbar;ratelimiter&period;h&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
class RateLimiter;
----

== Description

Units can be indicated to a rate limiter as consumed by either submitting them using the `submit` method&period; Units can be marked as reserved, which effectively shorten the sustained&hyphen;rate time&hyphen;window and the peak&hyphen;rate time&hyphen;window, by using the `reserve` method&period;

Whether submitting 1 more unit would exceed the configured limits can be determined using the `wouldExceedBandwidth` method&period; The estimated amount of time to wait before 1 more unit will be allowed to be submitted can be determined using the `calculateTimeToSubmit` method&period;

The state of a rate limiter must be updated manually using the `updateState` method supplying the current time interval&period; The time intervals supplied should all refer to the same time origin&period;

A rate limiter keeps some statistics, including the number of submitted units, that can be accessed using the `getStatistics` and reset using the `resetStatistics` method&period;

This class&colon; &ast; is _exception_ _neutral_ (agnostic) &ast; is _const_ _thread&hyphen;safe_ For terminology see `bsldoc&lowbar;glossary`&period;

== Member Functions

[cols="1,4"]
|===
| Name| Description
| xref:BloombergLP/balb/RateLimiter/2constructor.adoc[`RateLimiter`]         [.small]#[constructor]#
| Create a RateLimiter object, having the specified `sustainedRateLimit`, the specified `sustainedRateWindow`, the specified `peakRateLimit`, the specified `peakRateWindow`, and using the specified `currentTime` as the initial `lastUpdateTime`&period; The behavior is undefined unless `0 &lt; sustainedRateLimit`, `0 &lt; sustainedRateWindow`, `0 &lt; peakRateLimit`, `0 &lt; peakRateWindow`, the product of `sustainedRateLimit` and `sustainedRateWindow` can be represented by 64&hyphen;bit unsigned integral type, and the product of `peakRateLimit` and `peakRateWindow` can be represented by 64&hyphen;bit unsigned integral type&period;
| xref:BloombergLP/balb/RateLimiter/2destructor.adoc[`&#126;RateLimiter`] [.small]#[destructor]#
| Destroy this object&period;
| xref:BloombergLP/balb/RateLimiter/calculateTimeToSubmit.adoc[`calculateTimeToSubmit`] 
| Update the state of this rate limiter to the specified `currentTime`&period; Return the estimated time interval that should pass from `currentTime` until 1 more unit can be submitted to this rate limiter without exceeding its configured limits&period; The number of nanoseconds in the returned time interval is rounded up&period; Note that a time interval of 0 is returned if 1 or more units can be submitted at `currentTime`&period; Also note that after waiting for the returned time interval, clients should typically check again using this method, because additional units may have been submitted in the interim&period;
| xref:BloombergLP/balb/RateLimiter/cancelReserved.adoc[`cancelReserved`] 
| Cancel the specified `numUnits` that were previously reserved&period; The behavior is undefined unless `numUnits &lt;&equals; unitsReserved()`&period;
| xref:BloombergLP/balb/RateLimiter/getStatistics.adoc[`getStatistics`] 
| Load, into the specified `submittedUnits` and the specified `unusedUnits` respectively, the numbers of submitted units and the number of unused units for this rate limiter from the `statisticsCollectionStartTime` to the &apos;lastUpdateTime&period; The number of unused units is the difference between the number of units that could have been consumed at the sustained rate and the number of units actually submitted for the time period&period;
| xref:BloombergLP/balb/RateLimiter/lastUpdateTime.adoc[`lastUpdateTime`] 
| Return the time when this rate limiter was last updated&period;
| xref:BloombergLP/balb/RateLimiter/peakRateLimit.adoc[`peakRateLimit`] 
| Return the peak rate of this rate limiter&period;
| xref:BloombergLP/balb/RateLimiter/peakRateWindow.adoc[`peakRateWindow`] 
| Return the peak&hyphen;rate time&hyphen;period of this rate limiter&period; Note that this period is generally significantly shorter than `sustainedRateWindow`&period;
| xref:BloombergLP/balb/RateLimiter/reserve.adoc[`reserve`] 
| Reserve the specified `numUnits` for future use by this rate limiter&period; The behavior is undefined unless the sum of `numUnits`, unused units previously submitted to this rate limiter, and `unitsReserved` can be represented by a 64&hyphen;bit unsigned integral type&period;
| xref:BloombergLP/balb/RateLimiter/reset.adoc[`reset`] 
| Reset the statistics counter for this rate limiter to 0, and set the `lastUpdateTime` of this rate limiter to the specified `currentTime`&period;
| xref:BloombergLP/balb/RateLimiter/resetStatistics.adoc[`resetStatistics`] 
| Reset the statics collected for this rate limiter by setting the number of units used and the number of units submitted to 0, and set the `statisticsCollectionStartTime` to the `lastUpdateTime` of this leaky bucket&period;
| xref:BloombergLP/balb/RateLimiter/setRateLimits.adoc[`setRateLimits`] 
| Set the sustained rate of this rate limiter to the specified `sustainedRateLimit`, the sustained&hyphen;rate time&hyphen;window to the specified `sustainedRateWindow`, the peak rate to the specified `peakRateLimit` and the peak&hyphen;rate time&hyphen;window to the specified `peakRateWindow`&period; The behavior is undefined unless `0 &lt; sustainedRateLimit`, `0 &lt; sustainedRateWindow`, `0 &lt; peakRateLimit`, `0 &lt; peakRateWindow`, the product of `sustainedRateLimit` and `sustainedRateWindow` can be represented by 64&hyphen;bit unsigned integral type, and the product of `peakRateLimit` and `peakRateWindow` can be represented by 64&hyphen;bit unsigned integral type&period;
| xref:BloombergLP/balb/RateLimiter/statisticsCollectionStartTime.adoc[`statisticsCollectionStartTime`] 
| Return the time interval when the collection of the statistics (as returned by `getStatistics`) started&period;
| xref:BloombergLP/balb/RateLimiter/submit.adoc[`submit`] 
| Submit the specified `numUnits` to this rate limiter&period; The behavior is undefined unless the sum of `numUnits`, unused units previously submitted to this rate limiter, and `unitsReserved` can be represented by a 64&hyphen;bit unsigned integral type&period;
| xref:BloombergLP/balb/RateLimiter/submitReserved.adoc[`submitReserved`] 
| Submit the specified `numUnits` that were previously reserved&period; The behavior is undefined unless `numUnits &lt;&equals; unitsReserved()`&period;
| xref:BloombergLP/balb/RateLimiter/sustainedRateLimit.adoc[`sustainedRateLimit`] 
| Return the sustained rate of this rate limiter&period;
| xref:BloombergLP/balb/RateLimiter/sustainedRateWindow.adoc[`sustainedRateWindow`] 
| Return the sustained&hyphen;rate time&hyphen;period of this rate limiter&period; Note that this period is generally significantly longer than the `peakRateWindow`&period;
| xref:BloombergLP/balb/RateLimiter/unitsReserved.adoc[`unitsReserved`] 
| Return the number of reserved units for this rate limiter&period;
| xref:BloombergLP/balb/RateLimiter/updateState.adoc[`updateState`] 
| Set the `lastUpdateTime` of this rate limiter to the specified `currentTime`&period; If the `currentTime` is after `lastUpdateTime`, then recalculate number of units available for consumption based on the `peakRate`, `sustainedRate` and the time interval between `lastUpdateTime` and `currentTime`&period; If `currentTime` is before `statisticsCollectionStartTime`, set it&apos; to `currentTime`&period;
| xref:BloombergLP/balb/RateLimiter/wouldExceedBandwidth.adoc[`wouldExceedBandwidth`] 
| Update the state of this rate limiter to the specified `currentTime`&period; Return `true` if submitting 1 unit at the `currentTime` would exceed the configured limits, and false otherwise&period;
|===


== Static Member Functions

[cols="1,4"]
|===
| Name| Description
| xref:BloombergLP/balb/RateLimiter/supportsRateLimitsExactly.adoc[`supportsRateLimitsExactly`] 
| Returns `true` if, supposing the specified `sustainedRateLimit`, `sustainedRateWindow`, `peakRateLimit`, and `peakRateWindow` are used to initialize a `RateLimiter` object, the corresponding query methods return the same values&period; The implementation of `RateLimiter` uses `balb&colon;&colon;LeakyBucket` objects, and for some combinations of values the capacity of the `balb&colon;&colon;LeakyBucket` is rounded such that the rederived values differ&period; Note that this method is most likely to return `true` when the product of each corresponding pair of limit and window (as a fraction of a second) is integral&period;
|===



[.small]#Created with https://www.mrdocs.com[MrDocs]#
