This module implements rate-limiting functionality for Haskell programs. Rate-limiting is useful when trying to control / limit access to a particular resource over time. For example, you might want to limit the rate at which you make requests to a server, as an administrator may block your access if you make too many requests too quickly. Similarly, one may wish to rate-limit certain communication actions, in order to avoid accidentally performing a denial-of-service attack on a critical resource.
The fundamental idea of this library is that given some basic information about the requests you wante rate limited, it will return you a function that hides all the rate-limiting detail. In short, you make a call to one of the function generators in this file, and you will be returned a function to use. For example:
do f <- generateRateLimitedFunction ... ... res1 <- f a ... res2 <- f b ...
The calls to the generated function (f) will be rate limited based on the
parameters given to generateRateLimitedFunction
.
generateRateLimitedFunction
is the most general version of the rate
limiting functionality, but specialized versions of it are also exported
for convenience.
- generateRateLimitedFunction :: TimeUnit t => RateLimit t -> (req -> IO resp) -> ResultsCombiner req resp -> IO (req -> IO resp)
- data TimeUnit a => RateLimit a
- type ResultsCombiner req resp = req -> req -> Maybe (req, resp -> (resp, resp))
- dontCombine :: ResultsCombiner a b
- rateLimitInvocation :: TimeUnit t => t -> (req -> IO resp) -> IO (req -> IO resp)
- rateLimitExecution :: TimeUnit t => t -> (req -> IO resp) -> IO (req -> IO resp)
Documentation
generateRateLimitedFunctionSource
:: TimeUnit t | |
=> RateLimit t | What is the rate limit for this action |
-> (req -> IO resp) | What is the action you want to rate limit, given as an a MonadIO function from requests to responses? |
-> ResultsCombiner req resp | A function that can combine requests if rate
limiting happens. If you cannot combine two
requests into one request, we suggest using
|
-> IO (req -> IO resp) |
The most generic way to rate limit an invocation.
type ResultsCombiner req resp = req -> req -> Maybe (req, resp -> (resp, resp))Source
In some cases, if two requests are waiting to be run, it may be possible to combine them into a single request and thus increase the overall bandwidth. The rate limit system supports this, but requires a little additional information to make everything work out right. You may also need to do something a bit wonky with your types to make this work ... sorry.
The basic idea is this: Given two requests, you can either return Nothing (signalling that the two requests can be combined), or a Just with a new request representing the combination of the two requests. In addition, you will need to provide a function that can turn the response to this single request into two responses, one for each of the original requests.
I hope this description helps you work through the type, which I'll admit is a bit opaque.
dontCombine :: ResultsCombiner a bSource
rateLimitInvocation :: TimeUnit t => t -> (req -> IO resp) -> IO (req -> IO resp)Source
Rate limit the invocation of a given action. This is equivalent to calling
generateRateLimitedFunction
with a PerInvocation
rate limit and the
dontCombine
combining function.
rateLimitExecution :: TimeUnit t => t -> (req -> IO resp) -> IO (req -> IO resp)Source
Rate limit the execution of a given action. This is equivalent to calling
generateRateLimitedFunction
with a PerExecution
rate limit and the
dontCombine
combining function.