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 is the most general version of the rate
limiting functionality, but specialized versions of it are also exported
- 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)
|:: 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.
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.