Skip to content

Latest commit

 

History

History
70 lines (43 loc) · 3.39 KB

README.rdoc

File metadata and controls

70 lines (43 loc) · 3.39 KB

Prop

Prop is a simple gem for rate limiting requests of any kind. It allows you to configure hooks for registering certain actions, such that you can define thresholds, register usage and finally act on exceptions once thresholds get exceeded.

To get going with Prop you first define the read and write operations. These define how you write a registered request and how to read the number of requests for a given action. For example do something like the below in a Rails initializer:

Prop.read do |key|
  Rails.cache.read(key)
end

Prop.write do |key, value|
  Rails.cache.write(key, value)
end

You can choose to rely on a database or Moneta or Redis or whatever you’d like to use for transient storage. Prop does not do any sort of clean up of its key space, so you would have to implement that manually should you be using anything but an LRU cache.

Once the read and write operations are defined, you can optionally define some preconfigured default thresholds. If for example, you want to have a threshold on accepted emails per hour from a given user, you could define a threshold and interval (in seconds) for this like so:

Prop.setup(:mails_per_hour, :threshold => 100, :interval => 1.hour)

This results in a the following methods being generated:

# Throws Prop::RateLimitExceededError if the threshold/interval has been reached
Prop.throttle_mails_per_hour!

# Returns true if the threshold/interval has been reached
Prop.throttle_mails_per_hour?

# Sets the counter to 0
Prop.reset_mails_per_hour

In many cases you will want to tie a specific key to a defined throttle, for example you can scope the throttling to a specific sender rather than running a global “mails per hour” throttle:

Prop.throttle_mails_per_hour!(mail.from)

If this method gets called more than “threshold” times within “interval in seconds” Prop throws a Prop::RateLimitExceededError.

You can chose to override the threshold for a given key:

Prop.throttle_mails_per_hour!(mail.from, :threshold => account.mail_throttle_threshold)

If you wish to reset a specific throttle, you can do that like so:

Prop.reset_mails_per_hour(mail.from)

When the threshold are invoked without argument, the key is nil and as such a scope of its own.

Lastly you can use Prop without registering the thresholds up front:

Prop.throttle!(:key => 'nuisance@example.com', :threshold => 100, :interval -> 1.hour)
Prop.throttle?(:key => 'nuisance@example.com', :threshold => 100, :interval -> 1.hour)
Prop.reset(:key => 'nuisance@example.com', :threshold => 100, :interval -> 1.hour)
Prop.count(:key => 'nuisance@example.com', :threshold => 100, :interval -> 1.hour)

It’s up to you to pass an appropriate key which reflects the scope you’re rate limiting. The interval is tied to the underlying key generating mechanism, so if you change that between calls and have all other things equal, then that will result in different throttles being set.

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright © 2010 Morten Primdahl. See LICENSE for details.