parrish/Congestion

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Congestion

[![Build Status](https://travis-ci.org/parrish/Congestion.svg?branch=master)](https://travis-ci.org/parrish/Congestion)
[![Test Coverage](https://codeclimate.com/github/parrish/Congestion/badges/coverage.svg)](https://codeclimate.com/github/parrish/Congestion)
[![Code Climate](https://codeclimate.com/github/parrish/Congestion/badges/gpa.svg)](https://codeclimate.com/github/parrish/Congestion)
[![Gem Version](https://badge.fury.io/rb/congestion.svg)](http://badge.fury.io/rb/congestion)

A Redis rate limiter that provides both time-based limits and quantity-based limits based on [classdojo/rolling-rate-limiter](https://github.com/classdojo/rolling-rate-limiter).

## Middleware

- [Sidekiq-Congestion](https://github.com/parrish/Sidekiq-Congestion)
- [Rack-Congestion](https://github.com/parrish/Rack-Congestion)

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'congestion'
```

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install congestion

## Usage

### Making requests

```ruby
limiter = Congestion.request 'some_key'
```

Where `'some_key'` is an identifier for this request.

A common use case might be to set rate limits per user with something like `"#{ user.id }_some_key"`.

`Congestion.request` returns an an instance that provides information about the request:

```ruby
limiter.allowed?      # => true if the request is permitted
limiter.rejected?     # => true if the request is not permitted
limiter.too_many?     # => true if there are too many requests in the interval
limiter.too_frequent? # => true if the requests are arriving too quickly
limiter.backoff       # => the number of seconds before a request will be permitted
```

### Configuration

A proc provides a Redis connection:

```ruby
Congestion.redis = ->{
  Redis.new url: 'redis://:password@host:port/db'
}
```

To pool, your Redis connections:

```ruby
require 'congestion/redis_pool'

Congestion::RedisPool.redis_config = {
  url: 'redis://:password@host:port/db'
}

Congestion::RedisPool.pool_size = 10  # number of connections to use
Congestion::RedisPool.timeout = 10    # seconds before timing out an operation

Congestion.redis = Congestion::RedisPool.instance
```

Global options can be set with:

```ruby
Congestion.default_options = {
  namespace: 'congestion' # The Redis key prefix (e.g. 'congestion:some_key')
  interval: 1,            # The timeframe to limit within in seconds
  max_in_interval: 1,     # The number of allowed requests within the interval
  min_delay: 0.0,         # The minimum amount of time in seconds between requests
  track_rejected: true    # True if rejected request count towards the limit
}
```

Per-request options can be set as well:

```ruby
Congestion.request 'some_key', interval: 60, min_delay: 1
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To run the specs, run `bundle exec rake`.

## Contributing

1. Fork it ( https://github.com/parrish/congestion/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request