Skip to content
Roman edited this page Apr 28, 2025 · 1 revision

RateLimiterEtcd / RateLimiterEtcdNonAtomic

The rate limiter has been tested with the etcd version 3.5 and the etcd3 package version 1.1.

Atomic vs Non-Atomic

The rate limiter for the etcd store is offered in two different flavors - RateLimiterEtcd and RateLimiterEtcdNonAtomic.

As the etcd store does not offer an atomic operation to easily add a value to the actual rate, there is a non-atomic version of the etcd rate limiter which uses a combination of a simple get and put request on the etcd store. The update will be fast, but an atomic increment is not guaranteed on the RateLimiterEtcdNonAtomic class.

The RateLimiterEtcd class instead implements the _upsert method by using a conditional write. This conditional write works like a transaction as follows:

  1. Build the new value B for the given key.
  2. Get the old value A for the given key from the store
  3. Conditionally write the new value B for the given key if and only if the key still holds the old value A.
  4. If the conditional write fails go back to step #2 four times.
  5. If the conditional write has still not succeeded, bail out.

Usage

const { Etcd3 } = require('etcd3');

const RateLimiterEtcd = require('../lib/RateLimiterEtcd');

// First create the store client.
const etcdClient = new Etcd3({
  hosts: 'http://localhost:2379',
});

// Then create the etcd limiter with the given store instance.
const rateLimiter = new RateLimiterEtcd({
  storeClient: etcdClient,
  points: 2,
  duration: 5,
});

rateLimiter
  .consume(testKey, 1)
  .then((res) => {
    // Apply some app logic
  })
  .catch((rateLimiterResOrError) => {
    // Not enough points to consume or error happened
  });

The same logic applies to the non-atomic rater limiter class RateLimiterEtcdNonAtomic.

Clone this wiki locally