Skip to content

v3.0.0

Choose a tag to compare

@garvit-joshi garvit-joshi released this 06 Feb 19:23
· 46 commits to main since this release

v3.0.0

Added

  • Distributed Rate Limiting - New @RateLimit annotation for controlling request throughput across distributed systems (#44, #7)

    • Configurable permits and interval (e.g., 100 requests per minute)
    • Support for OVERALL (shared) and PER_CLIENT (per Redisson instance) rate types via RateType enum
    • SKIP_IMMEDIATELY and WAIT_AND_SKIP acquisition modes
    • RateLimitSkipHandler interface with RateLimitThrowExceptionHandler and RateLimitReturnDefaultHandler built-in handlers
    • RateLimitContext record for handler context
    • RateLimitExceededException for when rate limit is exceeded
    • LocksmithRateLimitTemplate for programmatic rate limiting with fluent builder
    • RateLimitCallback functional interface
    • RateLimitMetrics - Micrometer metrics integration (opt-in via locksmith.rate-limit.metrics-enabled)
    • SpEL expression support for dynamic keys
  • Enabled Property - Conditionally disable lock, semaphore, and rate-limit components

    • locksmith.lock.enabled (default: true)
    • locksmith.semaphore.enabled (default: true)
    • locksmith.rate-limit.enabled (default: true)
    • Uses @ConditionalOnProperty to conditionally create aspects and templates

Changed

  • Thread safety documentation added to Context records clarifying that args arrays are read-only by convention

Dependencies

  • Bumped Redisson from 4.1.0 to 4.2.0
  • Bumped maven-compiler-plugin from 3.14.1 to 3.15.0

Upgrade Guide

Update your dependency version:

<dependency>
    <groupId>in.riido</groupId>
    <artifactId>locksmith-spring-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>

New Rate Limiting Feature

Use the new @RateLimit annotation for throughput control:

// 100 requests per minute
@RateLimit(key = "heavy-api", permits = 100, interval = "1m")
public Response heavyOperation() {
    return processRequest();
}

// Per-user rate limiting with SpEL
@RateLimit(key = "#{#userId}", permits = 60, interval = "1m")
public Response userRequest(String userId) {
    return processRequest();
}

Or use the programmatic template:

@Service
public class MyService {

    private final LocksmithRateLimitTemplate rateLimitTemplate;

    public String example() throws Exception {
        return rateLimitTemplate.executeWithRateLimit("api", () -> {
            return "executed";
        });
    }

    public void builderExample() throws Exception {
        rateLimitTemplate.forKey("api")
            .permits(100)
            .interval(Duration.ofMinutes(1))
            .rateType(RateType.PER_CLIENT)
            .execute(() -> doWork());
    }
}

Disable Components

locksmith:
  lock:
    enabled: false      # Disable distributed locks
  semaphore:
    enabled: true
  rate-limit:
    enabled: true

Full Changelog: v2.1.0...v3.0.0