Skip to content

A Redis-based rate-limiter for sensitive, time-critical API access restrictions

Notifications You must be signed in to change notification settings

rstrobl/rate_limited_scheduler

Repository files navigation

Rate-limited Scheduler

Build Status

This rate-limited scheduler is made for requests to APIs with sensitive, time-critical access restrictions which means that even limits with short time intervals such as 5 requests per second can be hold in a multi-threading environment. It implements Redis-based execution handles.

Motivation

After investigating on other rate-limiters I figured out that most of them just start counting at the entry point of an execution unit. If this execution unit makes API requests, the actual request time that reaches the server can be anywhere between the entry point and the exit point. This might lead to scheduling conflicts since requests at the end of one timeslot get close to units from the next timeslot. In this rate-limiter I make use of the exit point in order to ensure that the API limits are even hold for short-time intervals. The implementation uses Redis-based execution handles which allows to also provide full functionality in multi-threading environment.

Outlook

This rate-limiter must not be used for API limits only of course. Another use-case would be to frequently send emails during a given time interval. If you have other use-cases I am curious to know about it. Please send me an email.

Installation

gem install rate_limited_scheduler

Usage

# instantiate RateLimitedScheduler with Redis bucket named :api_requests and a rate of 5 executions / 0.5 seconds
ratelimiter = RateLimitedScheduler.new(:api_requests, {:threshold => 5, :interval => 0.5})

10.times do
  ratelimiter.within_constraints do
    # make API request
  end
end

This would be a sequential run. But you can also use threads:

10.times do
  new Thread {
    ratelimiter.within_constraints do
      # make API request
    end
  }
end

You can also nest rate-limiters for multiple API limits:

# allow 2000 executions per day and 5 executions / second
day_ratelimiter = RateLimitedScheduler.new(:day_requests, {:threshold => 3000, :interval => 86400})
second_ratelimiter = RateLimitedScheduler.new(:second_requests, {:threshold => 5, :interval => 1})

5000.times do
  day_ratelimiter.within_constraints do
    second_ratelimiter.within_constraints do
      # make API request
    end
  end
end

About

A Redis-based rate-limiter for sensitive, time-critical API access restrictions

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages