Documentation ¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Buckets ¶
type Buckets interface { Inc(key string, id int64) error Del(key string, ids ...int64) error Get(key string, ids ...int64) ([]int64, error) }
Buckets a set of bucket, each bucket compute and return the number of occurs in itself
type BucketsFactory ¶
BucketsFactory a interface to create Buckets
func NewRedigoBuckets ¶
func NewRedigoBuckets(redis *redis.Pool) BucketsFactory
NewRedigoBuckets is a RedigoBuckets factory
func NewRedisV5Buckets ¶
func NewRedisV5Buckets(redis *redis.Client) BucketsFactory
NewRedisV5Buckets is a RedisV5Buckets factory
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter count total occurs during a period, it will store occurs during every time slice interval: (now ~ now - interval), (now - interval ~ now - 2*interval)...
Example ¶
package main import ( "fmt" "time" "github.com/abo/rerate" "github.com/gomodule/redigo/redis" ) func newRedigoPool(server, password string) *redis.Pool { return &redis.Pool{ MaxIdle: 3, IdleTimeout: 240 * time.Second, Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", server) if err != nil { return nil, err } if len(password) == 0 { return c, err } if _, err := c.Do("AUTH", password); err != nil { c.Close() return nil, err } return c, err }, TestOnBorrow: func(c redis.Conn, t time.Time) error { _, err := c.Do("PING") return err }, } } func main() { redigoBuckets := rerate.NewRedigoBuckets(newRedigoPool("localhost:6379", "")) key := "pv-home" // pv count in 5s, try to release per 0.5s counter := rerate.NewCounter(redigoBuckets, "rr:test:count", 5*time.Second, 500*time.Millisecond) counter.Reset(key) ticker := time.NewTicker(1000 * time.Millisecond) go func() { for range ticker.C { counter.Inc(key) } }() time.Sleep(4500 * time.Millisecond) ticker.Stop() total, _ := counter.Count(key) his, _ := counter.Histogram(key) fmt.Println("total:", total, ", histogram:", his) }
Output: total: 4 , histogram: [0 1 0 1 0 1 0 1 0 0]
func NewCounter ¶
func NewCounter(newBuckets BucketsFactory, prefix string, period, interval time.Duration) *Counter
NewCounter create a new Counter
type Limiter ¶
type Limiter struct { Counter // contains filtered or unexported fields }
Limiter a redis-based ratelimiter
Example ¶
package main import ( "fmt" "time" "github.com/abo/rerate" "github.com/gomodule/redigo/redis" ) func newRedigoPool(server, password string) *redis.Pool { return &redis.Pool{ MaxIdle: 3, IdleTimeout: 240 * time.Second, Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", server) if err != nil { return nil, err } if len(password) == 0 { return c, err } if _, err := c.Do("AUTH", password); err != nil { c.Close() return nil, err } return c, err }, TestOnBorrow: func(c redis.Conn, t time.Time) error { _, err := c.Do("PING") return err }, } } func main() { redigoBuckets := rerate.NewRedigoBuckets(newRedigoPool("localhost:6379", "")) key := "pv-dashboard" // rate limit to 10/2s, release interval 0.2s limiter := rerate.NewLimiter(redigoBuckets, "rr:test:limit", 2*time.Second, 200*time.Millisecond, 10) limiter.Reset(key) ticker := time.NewTicker(200 * time.Millisecond) go func() { for range ticker.C { limiter.Inc(key) if exceed, _ := limiter.Exceeded(key); exceed { ticker.Stop() } } }() time.Sleep(20 * time.Millisecond) for i := 0; i < 20; i++ { time.Sleep(200 * time.Millisecond) if exceed, _ := limiter.Exceeded(key); exceed { fmt.Println("exceeded") } else { rem, _ := limiter.Remaining(key) fmt.Println("remaining", rem) } } }
Output:
func NewLimiter ¶
func NewLimiter(newBuckets BucketsFactory, pfx string, period, interval time.Duration, max int64) *Limiter
NewLimiter create a new redis-based ratelimiter the Limiter limits the rate to max times per period
type RedigoBuckets ¶
type RedigoBuckets struct {
// contains filtered or unexported fields
}
RedigoBuckets is a Buckets using redigo as backend
func (*RedigoBuckets) Del ¶
func (bs *RedigoBuckets) Del(key string, ids ...int64) error
Del delete bucket key:ids, or delete Buckets key when ids is empty.
type RedisV5Buckets ¶
type RedisV5Buckets struct {
// contains filtered or unexported fields
}
RedisV5Buckets is a Buckets using redis.v5 as backend
func (*RedisV5Buckets) Del ¶
func (bs *RedisV5Buckets) Del(key string, ids ...int64) error
Del delete bucket key:ids, or delete Buckets key when ids is empty.