Giter Club home page Giter Club logo

pacemaker's Introduction

PaceMaker

Rate limit library

Implemented rate limits:

Fixed window rate limit

Fixed window limits—such as 3,000 requests per hour or 10 requests per day—are easy to state, but they are subject to have spikes at the edges of the window, as available quota resets. Consider, for example, a limit of 3,000 requests per hour, which still allows for a spike of all 3,000 requests to be made in the first minute of the hour, which might overwhelm the service.

Starts counting time windows when the first request arrives.

Example

Fixed truncated window rate limit

Same as Fixed Window rate limit but truncates the rate limit window to the rate interval configured in order to adjust to real time intervals passing. E.g:

  1. Rate limit interval is configured for new windows every 10 seconds
  2. First request arrives at 2022-02-05 10:23:23
  3. Current rate limit window: from 2022-02-05 10:23:20 to 2022-02-05 10:23:30

Example

Fixed window with token bucket variant (token refill at window's rate)

Works as any other fixed-window rate limiter. However, the meaning of 'capacity' of the inner fixed-window rate limiter changes from the total amount of requests that can be made to the total amount of tokens (points) that can be spent in that same window. This variant is particularly useful, for instance, when working on the crypto game field as many crypto exchanges employ this strategy. Take for example, binance.

Example


You can refer to google architecture docs to read more about rate limits.

Storages

  • Memory. Useful for non-distributed applications and testing purposes. Do not use on production unless you deliberately don't care about keeping rate limit state.
  • Redis. github.com/go-redis/redis is employed as Redis client

TODO:

  • Token bucket rate limit
  • Leaky bucket rate limit
  • Composite rate limit
  • Service rate limit

pacemaker's People

Contributors

sonirico avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

pacemaker's Issues

FixedTruncatedWindowRateLimiter Check() does not work correctly

	rateLimit := pacemaker.NewTokenFixedWindowRateLimiter(
		pacemaker.NewFixedTruncatedWindowRateLimiter(
			pacemaker.FixedTruncatedWindowArgs{
				Capacity: cfg.Capacity,
				Rate: pacemaker.Rate{
					Unit:   cfg.Rate.Unit,
					Amount: cfg.Rate.Amount,
				},
				Clock: cfg.Clock,
				DB: pacemaker.NewFixedWindowRedisStorage(
					cfg.RedisCli,
					pacemaker.FixedWindowRedisStorageOpts{
						Prefix: cfg.Bucket,
					},
				),
			},
		),
	)

	result, err := rateLimit.Try(context.Background(), 1)
	if err != nil {
		log.Errorf("error try: '%v'", err)
	}

	log.Debugf("Try Result: '%v'", result)

	result, err = rateLimit.Check(context.Background(), 1)
	if err != nil {
		log.Errorf("error try: '%v'", err)
	}

	log.Debugf("Check Result: '%v'", result)
$ go run examples/rate_limits/main.go                                            
2022-11-04T12:48:03Z - DEBUG - {"service":"example"} - connected to redis
2022-11-04T12:48:03Z - DEBUG - {"service":"example"} - Try Result: '{0s 159990}'
2022-11-04T12:48:03Z - DEBUG - {"service":"example"} - Check Result: '{0s 159990}'
$ go run examples/rate_limits/main.go                                            
2022-11-04T12:48:07Z - DEBUG - {"service":"example"} - connected to redis
2022-11-04T12:48:07Z - DEBUG - {"service":"example"} - Try Result: '{0s 159989}'
2022-11-04T12:48:07Z - DEBUG - {"service":"example"} - Check Result: '{0s 159989}'
$ go run examples/rate_limits/main.go                                            
2022-11-04T12:48:24Z - DEBUG - {"service":"example"} - connected to redis
2022-11-04T12:48:24Z - DEBUG - {"service":"example"} - Try Result: '{0s 159988}'
$ go run examples/rate_limits/main.go                                            
2022-11-04T12:48:42Z - DEBUG - {"service":"example"} - connected to redis
2022-11-04T12:48:42Z - DEBUG - {"service":"example"} - Check Result: '{0s 160000}'
$ go run examples/rate_limits/main.go                                            
2022-11-04T12:48:45Z - DEBUG - {"service":"example"} - connected to redis
2022-11-04T12:48:45Z - DEBUG - {"service":"example"} - Check Result: '{0s 160000}'
$ go run examples/rate_limits/main.go                                            
2022-11-04T12:49:03Z - DEBUG - {"service":"example"} - connected to redis
2022-11-04T12:49:03Z - DEBUG - {"service":"example"} - Try Result: '{0s 159987}'
2022-11-04T12:49:03Z - DEBUG - {"service":"example"} - Check Result: '{0s 159987}'

If we run both(try/check) the returned value by Check method is correct.

If we run only the check method, the returned value of Check methods is the capacity of the bucket instead of the remaining value.

FixedWindowRateLimiter

Not consistent across restarts as deadline is always moving alongside time. For more information refer to FIXMEs on impl.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.