Class RateLimitStatus
- java.lang.Object
-
- com.google.common.flogger.RateLimitStatus
-
public abstract class RateLimitStatus extends Object
Status for rate limiting operations, usable by rate limiters and available to subclasses ofLogContextto handle rate limiting consistently.Design Notes
The purpose of this class is to allow rate limiters to behave in a way which is consistent when multiple rate limiters are combined for a single log statement. If you are writing a rate limiter for Flogger which you want to "play well" with other rate limiters, it is essential that you understand how
RateLimitStatusis designed to work.Firstly,
LogContexttracks a single status for each log statement reached. This is modified by code in thepostProcess()method (which can be overridden by custom logger implementations).When a rate limiter is used, it returns a
RateLimitStatus, which is combined with the existing value held in the context:rateLimitStatus = RateLimitStatus.combine(rateLimitStatus, MyCustomRateLimiter.check(...));>/pre>A rate limiter should switch between two primary states "limiting" and "pending":
- In the "limiting" state, the limiter should return the
DISALLOWvalue and update any internal state until it reaches its trigger condition. Once the trigger condition is reached, the limiter enters the "pending" state. - In the "pending" state, the limiter returns an "allow" status until it is
reset().
This two-step approach means that, when multiple rate limiters are active for a single log statement, logging occurs after all rate limiters are "pending" (and at this point they are all reset). This is much more consistent than having each rate limiter operate independently, and allows a much more intuitive understanding of expected behaviour.
It is recommended that most rate limiters should start in the "pending" state to ensure that the first log statement they process is emitted (even when multiple rate limiters are used). This isn't required, but it should be documented either way.
Each rate limiter is expected to follow this basic structure:
{@code final class CustomRateLimiter extends RateLimitStatus { private static final LogSiteMapmap = new LogSiteMap () { - In the "limiting" state, the limiter should return the
-
-
Field Summary
Fields Modifier and Type Field Description static RateLimitStatusALLOWThe status to return whenever a stateless rate limiter determines that logging should occur.static RateLimitStatusDISALLOWThe status to return whenever a rate limiter determines that logging should not occur.
-
Constructor Summary
Constructors Modifier Constructor Description protectedRateLimitStatus()Rate limiters can extend this class directly if their "reset" operation is stateless, or they can create and return new instances to capture any necessary state.
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description protected abstract voidreset()Resets an associated rate limiter, moving it out of the "pending" state and back into rate limiting mode.
-
-
-
Field Detail
-
DISALLOW
public static final RateLimitStatus DISALLOW
The status to return whenever a rate limiter determines that logging should not occur.All other statuses implicity "allow" logging.
-
ALLOW
public static final RateLimitStatus ALLOW
The status to return whenever a stateless rate limiter determines that logging should occur.Note: Truly stateless rate limiters should be very rare, since they cannot hold onto a pending "allow" state. Even a simple "sampling rate limiter" should be stateful if once the "allow" state is reached it continues to be returned until logging actually occurs.
-
-
Method Detail
-
reset
protected abstract void reset()
Resets an associated rate limiter, moving it out of the "pending" state and back into rate limiting mode.Note: This method is never invoked concurrently with another
reset()operation, but it can be concurrent with calls to update rate limiter state. Thus it must be thread safe in general, but can assume it's the only reset operation active for the limiter which returned it.
-
-