poshjosh / rate-limiter-annotation

Rate limiting simplified with annotations

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

rate limiter - annotation

Distributed rate limiting simplified using annotations

We believe rate limiting should as easy as:

// All methods collectively limited to 10 permits per second
@Rate(10)
class RateLimitedResource {

    // 2 permits per second only when system free memory is less than 1GB
    @Rate(2) 
    @RateCondition("jvm.memory.free<1GB")
    @Path("/greet")
    public String greet(String who) {
        return "Hello " + who;
    }

    // 50 permits per minute
    @Rate(permits = 50, duration =  TimeUnit.MINUTES)
    @Path("/smile")
    public String smile() {
        return ":)";
    }
}

Based on rate-limiter.

Please first read the rate-limiter documentation.

For flexibility, this library offers a robust support for annotations.

If the target is web applications, consider using any of:

To add a dependency on rate-limiter-annotation using Maven, use the following:

        <dependency>
            <groupId>io.github.poshjosh</groupId>
            <artifactId>rate-limiter-annotation</artifactId>
            <version>0.5.0</version> 
        </dependency>

Concept

Unlike RateLimiter, ResourceLimiter introduces the concept of resources. One ResourceLimiter could be used to rate limit multiple resources distributed across different machines.

import java.util.Arrays;

class Concept {

    @Rate(name="resource-a", permits=1)
    static class ResourceA{}
    
    @Rate(name="resource-b", permits=5)
    static class ResourceB{}

    public static void main(String... args) {

        List<Class<?>> resourceClasses = Arrays.asList(ResourceA.class, ResourceB.class);

        ResourceLimiter<String> resourceLimiter = ResourceLimiter.of(resourceClasses);

        resourceLimiter.tryConsume("resource-a"); // true
        resourceLimiter.tryConsume("resource-a"); // false

        resourceLimiter.tryConsume("resource-b"); // false
    }
}

Sample Usage

import io.github.poshjosh.ratelimiter.ResourceLimiter;
import io.github.poshjosh.ratelimiter.annotations.Rate;

public class SampleUsage {

    static class RateLimitedResource {

        final ResourceLimiter<String> resourceLimiter;

        RateLimitedResource(ResourceLimiter<String> resourceLimiter) {
            this.resourceLimiter = resourceLimiter;
        }

        // Limited to 3 invocations every second
        @Rate(name = "smile", permits = 3)
        String smile() {
            if (!resourceLimiter.tryConsume("smile")) {
                throw new RuntimeException("Limit exceeded");
            }
            return ":)";
        }
    }

    public static void main(String... args) {

        ResourceLimiter<String> resourceLimiter = ResourceLimiter.of(RateLimitedResource.class);

        RateLimitedResource rateLimitedResource = new RateLimitedResource(resourceLimiter);

        int i = 0;
        for(; i < 3; i++) {

            System.out.println("Invocation " + i + " of 3 should succeed");
            rateLimitedResource.smile();
        }

        System.out.println("Invocation " + i + " of 3 should fail");
        rateLimitedResource.smile();
    }
}

Annotation Specification

Please read the annotation specs. It is concise.

Dependents

The following depend on this library:

About

Rate limiting simplified with annotations

License:Other


Languages

Language:Java 100.0%