Overview
The RateLimitPolicy class is an immutable model representing a rate limit policy: N requests per time window with an optional scope (e.g., per user, per IP).
Package: io.github.v4runsharma.ratelimiter.model
Source: RateLimitPolicy.java:7
Constructor
public RateLimitPolicy(int limit, Duration window, String scope)
Creates a new rate limit policy.
Maximum number of requests allowed within the window. Must be greater than 0.
Time window for the limit. Must be a positive, non-zero duration.
Scope identifier (e.g., “user”, “ip”, “global”). Normalized using RateLimitScope.from().
Throws: IllegalArgumentException if limit ≤ 0 or window is null/negative/zero.
Source: RateLimitPolicy.java:13-24
Properties
getLimit
The maximum number of requests allowed within the time window.
Source: RateLimitPolicy.java:26-28
getWindow
public Duration getWindow()
The time window duration for the rate limit.
Source: RateLimitPolicy.java:30-32
getScope
The normalized scope identifier (e.g., “USER”, “IP”, “GLOBAL”).
Source: RateLimitPolicy.java:34-36
Usage examples
Creating policies
import io.github.v4runsharma.ratelimiter.model.RateLimitPolicy;
import java.time.Duration;
// 100 requests per minute, user-scoped
RateLimitPolicy userPolicy = new RateLimitPolicy(
100,
Duration.ofMinutes(1),
"user"
);
// 1000 requests per hour, IP-scoped
RateLimitPolicy ipPolicy = new RateLimitPolicy(
1000,
Duration.ofHours(1),
"ip"
);
// 50 requests per 10 seconds, global scope
RateLimitPolicy globalPolicy = new RateLimitPolicy(
50,
Duration.ofSeconds(10),
"global"
);
Using with RateLimiter
import io.github.v4runsharma.ratelimiter.core.RateLimiter;
import io.github.v4runsharma.ratelimiter.model.RateLimitPolicy;
import io.github.v4runsharma.ratelimiter.model.RateLimitDecision;
import java.time.Duration;
public class RateLimitService {
private final RateLimiter rateLimiter;
public boolean checkUserLimit(String userId) {
// Create user-scoped policy
RateLimitPolicy policy = new RateLimitPolicy(
100,
Duration.ofMinutes(1),
"user"
);
// Evaluate
String key = "user:" + userId;
RateLimitDecision decision = rateLimiter.evaluate(key, policy);
return decision.isAllowed();
}
}
Converting from annotation
import io.github.v4runsharma.ratelimiter.annotation.RateLimit;
import io.github.v4runsharma.ratelimiter.model.RateLimitPolicy;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
public class PolicyConverter {
public static RateLimitPolicy fromAnnotation(RateLimit annotation) {
// Convert TimeUnit to ChronoUnit
ChronoUnit chronoUnit = annotation.timeUnit().toChronoUnit();
// Create duration
Duration window = Duration.of(annotation.duration(), chronoUnit);
// Create policy
return new RateLimitPolicy(
annotation.limit(),
window,
annotation.scope()
);
}
}
Policy comparison
import io.github.v4runsharma.ratelimiter.model.RateLimitPolicy;
import java.time.Duration;
public class PolicyManager {
public void comparePolicies() {
RateLimitPolicy policy1 = new RateLimitPolicy(
100,
Duration.ofMinutes(1),
"user"
);
RateLimitPolicy policy2 = new RateLimitPolicy(
100,
Duration.ofMinutes(1),
"user"
);
// Policies are equal
boolean isEqual = policy1.equals(policy2); // true
int hash1 = policy1.hashCode();
int hash2 = policy2.hashCode(); // same as hash1
}
}
Dynamic policy selection
import io.github.v4runsharma.ratelimiter.model.RateLimitPolicy;
import java.time.Duration;
public class DynamicPolicyProvider {
public RateLimitPolicy getPolicyForTier(String tier) {
return switch (tier.toUpperCase()) {
case "FREE" -> new RateLimitPolicy(
100,
Duration.ofMinutes(1),
"user"
);
case "PREMIUM" -> new RateLimitPolicy(
1000,
Duration.ofMinutes(1),
"user"
);
case "ENTERPRISE" -> new RateLimitPolicy(
10000,
Duration.ofMinutes(1),
"user"
);
default -> throw new IllegalArgumentException("Unknown tier: " + tier);
};
}
}
Validation
The constructor validates parameters:
// Valid policies
var valid1 = new RateLimitPolicy(1, Duration.ofSeconds(1), "user");
var valid2 = new RateLimitPolicy(1000, Duration.ofHours(24), "global");
// Invalid: limit must be > 0
try {
var invalid = new RateLimitPolicy(0, Duration.ofSeconds(1), "user");
} catch (IllegalArgumentException e) {
// "Limit must be greater than 0"
}
// Invalid: window must be positive
try {
var invalid = new RateLimitPolicy(10, Duration.ZERO, "user");
} catch (IllegalArgumentException e) {
// "Window must be a positive duration"
}
// Invalid: window cannot be null
try {
var invalid = new RateLimitPolicy(10, null, "user");
} catch (IllegalArgumentException e) {
// "Window must be a positive duration"
}
Immutability
All properties are immutable:
RateLimitPolicy policy = new RateLimitPolicy(
100,
Duration.ofMinutes(1),
"user"
);
// Properties are read-only
int limit = policy.getLimit(); // 100
Duration window = policy.getWindow(); // PT1M
String scope = policy.getScope(); // "USER"
// No setters available - policy is immutable
String representation
RateLimitPolicy policy = new RateLimitPolicy(
100,
Duration.ofMinutes(1),
"user"
);
System.out.println(policy);
// Output: RateLimitPolicy{limit=100, window=PT1M, scope='USER'}
Source: RateLimitPolicy.java:54-60