Class JdbcRateLimiter

java.lang.Object
com.codename1.backend.security.ratelimit.JdbcRateLimiter
All Implemented Interfaces:
RateLimiter

public final class JdbcRateLimiter extends Object implements RateLimiter

Counts in the server's database, in the cn1_rate_limit table of SecuritySchema, so that every process of a deployment shares one limit.

http.rateLimit("/login", RateLimitKeys.clientAddress(),
        new JdbcRateLimiter(dataSource, "login", 5, 60));

A fixed window: permits requests in each periodSeconds, counted from the first request of the window. Every request is decided by one conditional UPDATE and the number of rows it changed, so two processes counting at the same moment cannot both take the last permit.

It costs a statement or two per request it counts, which is the price of agreeing across processes; InMemoryRateLimiter costs none and counts for its own process alone. A database that cannot be reached refuses nobody: the limit is a courtesy to the server, and a store that is down must not take the application with it.

  • Constructor Summary

    Constructors
    Constructor
    Description
    JdbcRateLimiter(DataSource dataSource, String name, int permits, long periodSeconds)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    deleteExpired(long olderThanSeconds)
    Deletes the counts of every limiter whose window ended more than olderThanSeconds ago; for a scheduled job, since a key that is never seen again leaves its row behind.
    derive(String name, int permits, long periodSeconds)
    A limiter over the same table, under name, read on the same clock.
    void
    Deletes the row of key.
    long
    How many seconds a request just refused under key should wait before trying again: what its Retry-After says.
    void
    setClock(Clock clock)
     
    boolean
    Counts one request under key.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • JdbcRateLimiter

      public JdbcRateLimiter(DataSource dataSource, String name, int permits, long periodSeconds)
      Parameters:
      name - what keeps this limiter's counts apart from another's in the same table; two limiters of one name share their counts on purpose
  • Method Details

    • derive

      public RateLimiter derive(String name, int permits, long periodSeconds)
      A limiter over the same table, under name, read on the same clock.
      Specified by:
      derive in interface RateLimiter
      Parameters:
      name - what keeps the new limiter's counts apart
      permits - how many requests a key may make in a period
      periodSeconds - the length of the period
    • setClock

      public void setClock(Clock clock)
    • tryAcquire

      public boolean tryAcquire(String key)
      Description copied from interface: RateLimiter
      Counts one request under key.
      Specified by:
      tryAcquire in interface RateLimiter
      Returns:
      whether the request is within the limit
    • reset

      public void reset(String key)
      Deletes the row of key. A database that cannot be reached leaves the count as it is, which is the safe way round for a bound on guesses.
      Specified by:
      reset in interface RateLimiter
    • retryAfterSeconds

      public long retryAfterSeconds(String key)
      Description copied from interface: RateLimiter
      How many seconds a request just refused under key should wait before trying again: what its Retry-After says. One second unless the limiter knows better.
      Specified by:
      retryAfterSeconds in interface RateLimiter
    • deleteExpired

      public int deleteExpired(long olderThanSeconds) throws IOException
      Deletes the counts of every limiter whose window ended more than olderThanSeconds ago; for a scheduled job, since a key that is never seen again leaves its row behind.
      Returns:
      how many rows were deleted
      Throws:
      IOException