coveooss / spillway

A simple, distributed and flexible rate limiter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Spillway

Build Status license Maven Central

A distributed throttling solution

Spillway is an easy to use solution to add distributed throttling at the software level in your public API. This is particularly useful if multiple services are running in different JVMs. It is also possible to quickly to react when throttling happens with our built-in call-back mechanism.

Storage backend currently supported:

  • In memory (for usage within the same JVM)
  • Redis

All external storage can be (and should be) wrapped in our asynchronous storage to avoid slowing down/stopping queries if external problems occurs with the external storage.

Getting Started

Add Spillway to your project pom

<dependency>
    <groupId>com.coveo</groupId>
    <artifactId>spillway</artifactId>
    <version>2.0.0</version>
</dependency>

Documentation

The java documentation is available here: https://coveooss.github.io/spillway/

Usage

Sample 1
    LimitUsageStorage storage = new AsyncLimitUsageStorage(new RedisStorage("localhost"));
    SpillwayFactory spillwayFactory = new SpillwayFactory(storage);

    Limit<String> myLimit = LimitBuilder.of("myLimit").to(2).per(Duration.ofMinutes(1)).build();
    Spillway<String> spillway = spillwayFactory.enforce("myResource", myLimit);
    
    spillway.call("myLimit"); // nothing happens
    spillway.call("myLimit"); // nothing happens
    spillway.call("myLimit"); // throws SpillwayLimitExceededException
Sample 2
    LimitUsageStorage storage = new InMemoryStorage();
    SpillwayFactory spillwayFactory = new SpillwayFactory(storage);

    Limit<User> userLimit = LimitBuilder.of("perUser", User::getName).to(3).per(Duration.ofHours(1)).build();
    Limit<User> ipLimit = LimitBuilder.of("perIp", User::getIp).to(3).per(Duration.ofHours(1)).withExceededCallback(myCallback).build();
    Spillway<User> spillway = spillwayFactory.enforce("myResource", userLimit, ipLimit);

    User john = new User("john", "127.0.0.1");
    User gina = new User("gina", "127.0.0.1");

    spillway.tryCall(john); // true
    spillway.tryCall(gina); // true
    spillway.tryCall(john); // true
    spillway.tryCall(gina); // false, perIp limit exceeded.
Sample 3
    LimitUsageStorage storage = new InMemoryStorage();
    SpillwayFactory spillwayFactory = new SpillwayFactory(storage);
    
    LimitOverride override = LimitOverrideBuilder.of("john").to(10).per(Duration.ofHours(1)).build();
    Limit<String> userLimit = LimitBuilder.of("perUser").to(30).per(Duration.ofHours(1)).withLimitOverride(override).build();
    Spillway<User> spillway = spillwayFactory.enforce("myResource", userLimit);

    spillway.tryCall("john", 11); // false
    spillway.tryCall("gina", 20); // true

External Resources

cirrus-up-cloud wrote a nice blog post about using Spillway on AWS with Elasticache.

About

A simple, distributed and flexible rate limiter

License:MIT License


Languages

Language:Java 100.0%