Popularity
6.0
Growing
Activity
0.0
Stable
306
10
23

Programming language: Go
Tags: Utilities    

go-rate alternatives and similar packages

Based on the "Utilities" category

Do you think we are missing an alternative of go-rate or a related project?

Add another 'Utilities' Package

README

go-rate

Build Status GoDoc

go-rate is a rate limiter designed for a range of use cases, including server side spam protection and preventing saturation of APIs you consume.

It is used in production at LangTrend to adhere to the GitHub API rate limits.

Usage

Import github.com/beefsack/go-rate and create a new rate limiter with the rate.New(limit int, interval time.Duration) function.

The rate limiter provides a Wait() and a Try() (bool, time.Duration) method for both blocking and non-blocking functionality respectively.

API documentation available at godoc.org.

Examples

Blocking rate limiting

This example demonstrates limiting the output rate to 3 times per second.

package main

import (
    "fmt"
    "time"

    "github.com/beefsack/go-rate"
)

func main() {
    rl := rate.New(3, time.Second) // 3 times per second
    begin := time.Now()
    for i := 1; i <= 10; i++ {
        rl.Wait()
        fmt.Printf("%d started at %s\n", i, time.Now().Sub(begin))
    }
    // Output:
    // 1 started at 12.584us
    // 2 started at 40.13us
    // 3 started at 44.92us
    // 4 started at 1.000125362s
    // 5 started at 1.000143066s
    // 6 started at 1.000144707s
    // 7 started at 2.000224641s
    // 8 started at 2.000240751s
    // 9 started at 2.00024244s
    // 10 started at 3.000314332s
}

Blocking rate limiting with multiple limiters

This example demonstrates combining rate limiters, one limiting at once per second, the other limiting at 2 times per 3 seconds.

package main

import (
    "fmt"
    "time"

    "github.com/beefsack/go-rate"
)

func main() {
    begin := time.Now()
    rl1 := rate.New(1, time.Second)   // Once per second
    rl2 := rate.New(2, time.Second*3) // 2 times per 3 seconds
    for i := 1; i <= 10; i++ {
        rl1.Wait()
        rl2.Wait()
        fmt.Printf("%d started at %s\n", i, time.Now().Sub(begin))
    }
    // Output:
    // 1 started at 11.197us
    // 2 started at 1.00011941s
    // 3 started at 3.000105858s
    // 4 started at 4.000210639s
    // 5 started at 6.000189578s
    // 6 started at 7.000289992s
    // 7 started at 9.000289942s
    // 8 started at 10.00038286s
    // 9 started at 12.000386821s
    // 10 started at 13.000465465s
}

Non-blocking rate limiting

This example demonstrates non-blocking rate limiting, such as would be used to limit spam in a chat client.

package main

import (
    "fmt"
    "time"

    "github.com/beefsack/go-rate"
)

var rl = rate.New(3, time.Second) // 3 times per second

func say(message string) {
    if ok, remaining := rl.Try(); ok {
        fmt.Printf("You said: %s\n", message)
    } else {
        fmt.Printf("Spam filter triggered, please wait %s\n", remaining)
    }
}

func main() {
    for i := 1; i <= 5; i++ {
        say(fmt.Sprintf("Message %d", i))
    }
    time.Sleep(time.Second / 2)
    say("I waited half a second, is that enough?")
    time.Sleep(time.Second / 2)
    say("Okay, I waited a second.")
    // Output:
    // You said: Message 1
    // You said: Message 2
    // You said: Message 3
    // Spam filter triggered, please wait 999.980816ms
    // Spam filter triggered, please wait 999.976704ms
    // Spam filter triggered, please wait 499.844795ms
    // You said: Okay, I waited a second.
}

Authors