rate-limit-1.1.0: A basic library for rate-limiting IO actions.



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.





:: 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 dontCombine.

-> IO (req -> IO resp) 

The most generic way to rate limit an invocation.

data TimeUnit a => RateLimit a Source

The rate at which to limit an action.

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.

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.