limits

package
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 21, 2015 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Example (Basic)

Example_basic creates a new service under path "/" and serves requests for the count resource.

package main

import (
	"github.com/codehack/go-relax"
	"github.com/codehack/go-relax/limits"
	"time"
)

type Count int

func (c *Count) Index(ctx *relax.Context) {
	*c += 1
	ctx.Respond(c)
}

// Example_basic creates a new service under path "/" and serves requests
// for the count resource.
func main() {
	c := Count(0)
	svc := relax.NewService("/")

	// Memory limit check, allocation 250kb
	svc.Use(&limits.Memory{Alloc: 250 * 1024})

	// Throttle limit, 1 request per 200ms
	svc.Use(&limits.Throttle{
		Burst:    5,
		Requests: 1,
		Per:      time.Minute * 3,
	})

	// Usage limit check, 10 tokens
	svc.Use(&limits.Usage{
		Container: limits.NewRedisBucket("tcp://127.0.0.1", 10, 1),
	})

	svc.Resource(&c)
	svc.Run()
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func MD5RequestKey

func MD5RequestKey(c relax.Context) string

MD5RequestKey returns a key made from MD5 hash of Request.RemoteAddr and Request.UserAgent. But if the client has been authenticated, it will use the username as key.

func Min

func Min(a, b int) int

Min returns the smaller integer between a and b. If a is lesser than b it returns a, otherwise returns b.

func SplitPort

func SplitPort(addr string) (string, string)

SplitPort splits an host:port address and returns the parts.

Types

type Container

type Container interface {
	// Capacity returns the max number of tokens per client.
	Capacity() int

	// Consume takes tokens from a bucket.
	// Returns the number of tokens available, time in seconds for next one, and
	// a boolean indicating whether of not a token was consumed.
	Consume(string, int) (int, int, bool)

	// Reset will fill-up a bucket regardless of time/count.
	Reset(string)
}

Objects that implement the Container interface can serve as token bucket containers.

func NewMemBucket

func NewMemBucket(maxKeys, capacity, rate int) Container

NewMemBucket returns a new MemBucket container object. It initializes the LRU cache with 'maxKeys'.

type MemBucket

type MemBucket struct {
	Size  int        // max tokens allowed, capacity.
	Rate  int        // tokens added per minute
	Cache *lru.Cache // LRU cache storage
}

MemBucket implements Container using an in-memory LRU cache. This container is ideal for single-host applications, and it's go-routine safe.

func (*MemBucket) Capacity

func (b *MemBucket) Capacity() int

func (*MemBucket) Consume

func (b *MemBucket) Consume(key string, n int) (int, int, bool)

func (*MemBucket) Reset

func (b *MemBucket) Reset(key string)

type Memory

type Memory struct {
	// Allow sets a limit on current used memory size, in bytes. This value
	// ideally should be a number multiple of 2.
	// Defaults to 0 (disabled)
	// 	Alloc: 5242880 // 5MB
	Alloc uint64

	// Sys sets a limit on system memory usage size, in bytes. This value
	// ideally should be a number multiple of 2.
	// Defaults to 1e9 (1000000000 bytes)
	Sys uint64

	// RetryAfter is a suggested retry-after period, in seconds, as recommended
	// in http://tools.ietf.org/html/rfc7231#section-6.6.4
	// If zero, no header is sent.
	// Defaults to 0 (no header sent)
	RetryAfter int
}

Memory sets limits on application and system memory usage. The memory stats are updated every minute and compared. If any limit is reached, a response is sent with HTTP status 503-"Service Unavailable". See also, runtime.MemStats

func (*Memory) Run

func (f *Memory) Run(next relax.HandlerFunc) relax.HandlerFunc

Run processes the filter. No info is passed.

type RedisBucket

type RedisBucket struct {
	Size int // max tokens allowed
	Rate int // tokens added per second
	Pool *redis.Pool
}

RedisBucket implements Container using Redis strings.

func NewRedisBucket

func NewRedisBucket(uri string, capacity, rate int) *RedisBucket

func NewRedisBucket(uri string, capacity, rate int) Container {

func (*RedisBucket) Capacity

func (b *RedisBucket) Capacity() int

func (*RedisBucket) Consume

func (b *RedisBucket) Consume(key string, n int) (int, int, bool)

func (*RedisBucket) Reset

func (b *RedisBucket) Reset(key string)

type Throttle

type Throttle struct {
	// Request is the number of requests to allow per time duration.
	// Defaults to 100
	Requests int

	// Burst is the number of burst requests allowed before enforcing a time limit.
	// Defaults to 0
	Burst int

	// Per is the unit of time to quantize requests. This value is divided by the
	// value of Requests to get the time period to throttle.
	// Defaults to 1 second (time.Second)
	Per time.Duration
}

Throttle allows to limit the rate of requests to a resource per specific time duration. It uses Go's channels to receive time tick updates. If a request is made before the channel is updated, the request is dropped with HTTP status code 429-"Too Many Requests".

func (*Throttle) Run

func (f *Throttle) Run(next relax.HandlerFunc) relax.HandlerFunc

Run processes the filter. No info is passed.

type Usage

type Usage struct {
	// Container is an interface implemented by the bucket device.
	// The default container, MemBucket, is a memory-based container which stores
	// keys in an LRU cache. This container monitors a maximum number of keys,
	// and this value should be according to the system's available memory.
	// Defaults to a MemBucket container, with the values:
	//
	// 		maxKeys  = 1000 // number of keys to monitor.
	// 		capacity = 100  // total tokens per key.
	// 		fillrate = 1    // tokens renewed per minute per key.
	//
	// See also, MemBucket
	Container

	// Ration is the number of tokens to consume per request.
	// Defaults to 1.
	Ration int

	// Keygen is a function used to generate semi-unique ID's for each client.
	// The default function, MD5RequestKey, uses an MD5 hash on client address
	// and user agent, or the username of an authenticated client.
	Keygen func(relax.Context) string
}

Usage monitors request usage limits to the service, resource or to specific route(s). It uses Container objects to implement the token-bucket (TB) algorithm. TB is useful for limiting number of requests and burstiness.

Each client is assigned a (semi) unique key and given a bucket of tokens to spend per request. If a client consumes all its tokens, a response is sent with HTTP status 429-"Too Many Requests". At this time the client won't be allowed any more requests until a renewal period has passed. Repeated attempts while the timeout is in effect will simply reset the timer, prolonging the wait and dropping then new request.

See also, https://en.wikipedia.org/wiki/Token_bucket

func (*Usage) Run

func (f *Usage) Run(next relax.HandlerFunc) relax.HandlerFunc

Run processes the filter. No info is passed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL