Class Resilience4jEventRateLimiter

java.lang.Object
com.tnsai.quality.ratelimit.Resilience4jEventRateLimiter
All Implemented Interfaces:
EventRateLimiter

public final class Resilience4jEventRateLimiter extends Object implements EventRateLimiter
Token-bucket EventRateLimiter backed by Resilience4j (issue #82). Scopes one rate limiter per tenant via the RateLimiterRegistry; tenants without a custom configuration fall back to the shared default.

Defaults: 1000 events / second, refill window 1 second, non-blocking (timeoutDuration = 0). The non-blocking choice is deliberate — events are produced from agent runtime hot paths and blocking would back-pressure the agent itself, defeating the point.

Aggregate drop counter: drops are recorded per tenant (and total) so consumers can periodically log a summary (ratelimit.dropped events, in the cost-governance vocabulary) without burying every individual drop.

Since:
0.10.0 (issue #82)
  • Field Details

    • DEFAULT_TENANT

      public static final String DEFAULT_TENANT
      Tenant key used when EventContext.tenantId() is absent.
      See Also:
  • Constructor Details

    • Resilience4jEventRateLimiter

      public Resilience4jEventRateLimiter(io.github.resilience4j.ratelimiter.RateLimiterConfig defaultConfig)
      Construct with a shared registry + a default config. The default config is used when check(EventContext) sees a tenant for which no per-tenant config has been registered.
    • Resilience4jEventRateLimiter

      public Resilience4jEventRateLimiter(int limit, Duration period)
      Construct with a fresh registry using a default of limit permits per period (non-blocking).
    • Resilience4jEventRateLimiter

      public Resilience4jEventRateLimiter()
      Construct with the framework default of 1000 events / second.
  • Method Details

    • registerTenant

      public void registerTenant(String tenantId, io.github.resilience4j.ratelimiter.RateLimiterConfig config)
      Register a per-tenant override. Useful for paying tenants who earned more headroom, or for free-tier shrinking. Idempotent within a JVM — subsequent calls with the same tenantId replace the prior config.
    • check

      public Decision check(com.tnsai.observability.events.EventContext context)
      Description copied from interface: EventRateLimiter
      Decide whether the tenant can emit another event right now.
      Specified by:
      check in interface EventRateLimiter
      Parameters:
      context - the active event context (tenant, agent, trace)
      Returns:
      Decision.ACCEPT, Decision.DROP, or Decision.DEFER
    • flushDropCounters

      public Map<String,Long> flushDropCounters()
      Snapshot the per-tenant drop counter and reset it to zero. Use this on a scheduler (every minute, say) to emit a single ratelimit.dropped log line per tenant per window — dropped events are recorded in aggregate, never per-event.
      Returns:
      immutable map of tenant -> drops since the last flush
    • getDropCount

      public long getDropCount(String tenantId)
      Read the live drops counter for a tenant without resetting.