Code Monkey home page Code Monkey logo

traffic_jam's Introduction

TrafficJam

Build Status Coverage Status

This is a library for enforcing rate limits across concurrent processes. This can be used to cap the number of actions that may be performed in a certain period of time. More generally, this can be used to enforce a cap on an integer amount that can be incremented or decremented. A limit consists of an action name, a maximum amount, and a period of time in seconds.

Instead of guaranteeing that the number of actions will never exceed the cap the given timeframe, the approach we take is to use a continuously regenerating limit. The amount remaining will constantly increase at a rate of max / period until it hits the cap. If, for example, the limit is 60 per minute, a user could increment by 60 at once, then increment by 1 per second forever without hitting the cap. As a consequence, this algorithm guarantees that the total amount incremented will be less than twice the limit in any given timeframe.

Usage

require 'traffic_jam'

TrafficJam.configure do |config|
  config.redis = Redis.new(url: REDIS_URL)
end

limit = TrafficJam::Limit.new(
  :requests_per_user,
  user.id,
  max: 3,
  period: 1 # seconds
)
limit.increment      # => true
limit.increment(2)   # => true
limit.increment      # => false
limit.increment!     # => raises TrafficJam::LimitExceededError

sleep 1

limit.increment(2)   # => true
limit.exceeded?      # => false
limit.exceeded?(2)   # => true

limit.used           # => 2
limit.remaining      # => 1

Configuration

TrafficJam configuration object can be accessed with TrafficJam.config or in a block like TrafficJam.configure { |config| ... }. Configuration options are:

redis (required): A Redis instance to store amounts used for each limit.

key_prefix (default: "traffic_jam"): The string prefixing all keys in Redis.

Registering limits

Fixed limits can be registered for a key if the cap does not change depending on the value. All instance methods are available on the class.

TrafficJam.configure do |config|
  config.register(:requests_per_user, 3, 1)
end

limit = TrafficJam.limit(:requests_per_user, "user1")
limit.increment(2)  # => true

TrafficJam.increment(:requests_per_user, "user1", 1)  # => true
TrafficJam.used(:requests_per_user, "user1")          # => 3

Changing cap for a limit

Given an instance of TrafficJam::Limit with a maximum cap and a period, the behavior is to increase the amount remaining at a rate of max / period since the last time increment was called for the given value. If the cap is defined on a per-value basis, it is good practice to call increment(0) if the limit changes.

For example:

user.requests_per_hour = 10

limit = TrafficJam::Limit.new(
  :requests_per_user, user.id,
  max: user.requests_per_hour, period: 60 * 60
)
limit.increment(8)  # => true

sleep 60

limit.increment(0)

user.requests_per_hour = 20
limit = TrafficJam::Limit.new(
  :requests_per_user, user.id,
  max: user.requests_per_hour, period: 60 * 60
)
limit.increment(8)  # => true

Running tests

The REDIS_URI environment variable can be set in tests, and defaults to redis://localhost:6379.

rake test

To run a performance/stress test, see the test/stress.rb script.

traffic_jam's People

Contributors

jimpo avatar ashleym1972 avatar grahamjenson avatar dustmason avatar krobertson avatar pshc avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.