Giter Club home page Giter Club logo

cap5lut-ratelimits's Introduction

cap5lut-ratelimits Build Status

Rate limit system.

NOTE: Library is in an early development state and may undergo heavy changes

Installation:

Usage:

RateLimit

RateLimit has the method acquire(), this method blocks until it acquired a RateLimitSlot If execution shall be limited to 2 times per second, the RateLimit can be created like this:

RateLimit rateLimit = new ConcurrentRateLimit(2, 1, TimeUnit.SECONDS);

To limit the execution, simply call acquire() before execution.

for(int i = 0; i < 10; i++) {
    rateLimit.acquire();
    System.out.printf("%s: %d%n", Instant.now(), i);
}

RateLimited

RateLimited is an rate limited instance wrapper. Its acquire() method will acquire a slot from the underyling rate limits and return the instance.

There are two ways to create a RateLimited instance:

RateLimit.limit(instance)

An RateLimited instance can be created by using the RateLimits helper method limit(instance):

AtomicInteger instance = new AtomicInteger(0);
RateLimit rateLimit = new ConcurrentRateLimit(2, 1, TimeUnit.SECONDS);
RateLimited<AtomicInteger> number = rateLimit.limit(instance);

new RateLimited(instance, ratelimits)

Another way is to use the constructor directly:

AtomicInteger instance = new AtomicInteger(0);
RateLimit rateLimit = new ConcurrentRateLimit(2, 1, TimeUnit.SECONDS);
RateLimited<AtomicInteger> number = new RateLimited<>(instance, rateLimit);

Example

for (int i = 0; i < 10; i++) {
    System.out.println(number.acquire().incrementAndGet());
}

Complex rate limits

Sometimes rate limits are part of another rate limit (e.g. Discord's rate limits). The following example shows, how to use multiple rate limits.

In this example, two tasks should be executed 5 times each. Generally only 5 tasks shall be executed within 1 second, additionally task taskA shall be executed only 2 times per second.

Create the tasks:

Runnable taskAInstance = () -> System.out.printf("%s A%n", Instant.now());
Runnable taskBInstance = () -> System.out.printf("%s B%n", Instant.now());

Create the rate limits:

RateLimit globalLimit = new ConcurrentRateLimit(5, 1, TimeUnit.SECONDS);
RateLimit taskALimit = new ConcurrentRateLimit(2, 1, TimeUnit.SECONDS);

Create the rate limited instances:

RateLimited<Runnable> taskA = new RateLimited<Runnable>(taskAInstance, globalLimit, taskALimit);
RateLimited<Runnable> taskB = globalLimit.limit(taskBInstance);

Schedule the task execution:

ExecutorService executor = Executors.newCachedThreadPool();

for(int i = 0; i < 5; i++) {
    executor.submit(() -> {
        try {
            taskA.acquire().run();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}

for(int i = 0; i < 5; i++) {
    executor.submit(() -> {
        try {
            taskB.acquire().run();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}

Canceling an acquired rate limit slot

Sometimes its needed to cancel an acquired slot. By that is meant, that if you acquired a rate limit slot, but determined it is not needed anymore and should be returned to the rate limit.

RateLimit.acquire() returns a RateLimitSlot instance. This instance has a method called cancel(), which returns the acquired slot to the rate limit, if its still in the current rate.

cap5lut-ratelimits's People

Stargazers

Walker Knapp avatar

Watchers

James Cloos avatar Florian Pattke avatar

cap5lut-ratelimits's Issues

Dynamic rate limit support

From a quick glance, it doesn't seem that current implementation of ConcurrentRateLimit supports dynamic rate limits. A dynamic rate limit is considered a rate limit that changes its capacity either between results or between particular moments in time. An example of that is discord bot API, which provides rolling rate limits.

non-blocking example

Hi, your code looks neat.

This might not end up being a change here, but in our zipkin library we are working on a non-blocking rate limited implementation of sampling. For example, it returns true 1 time per second. I'm not sure if you have ambition for non-blocking. Also, we couldn't make a strict dependency, but it would be neat to get your input anyway. openzipkin/brave#819

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.