Skip to content

Instantly share code, notes, and snippets.

@unixcharles
Created May 2, 2017 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unixcharles/0f93d7dd360a29e56e51ea2bc81716f5 to your computer and use it in GitHub Desktop.
Save unixcharles/0f93d7dd360a29e56e51ea2bc81716f5 to your computer and use it in GitHub Desktop.
30 lines rate limited
# USAGE:
# rate_limiter = RateLimiter.new('throttle_key', limit: 5, ttl: 1.hour)
# rate_limiter.throttled { not_too_often }
#
class RateLimiter
attr_reader :topic, :limit, :ttl, :cache
def initialize(topic:, limit:, ttl:, cache: default_cache)
@topic, @limit, @ttl, @cache = topic, limit, ttl, cache
end
def throttled
raise LimitReached if entries.size > limit
update_entries
yield
end
private
def entries
Array(cache.get(topic)).map do |epoch|
Time.at(epoch)
end.reject do |entry|
(entry + ttl).past?
end
end
def update_entries
updated_entries = entries << Time.now
cache.write(entries.map(&:to_i), ttl)
end
def default_cache
Rails.cache
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment