ratelimit

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2021 License: MIT Imports: 3 Imported by: 0

README

GoDoc

ratelimit

ratelimit implements the x/sync/errgroup interface, but enforces a max throughput that the functions will be executed at. This is useful when making concurrent requests to backends that have either have rate limiting or cannot handle excessive throughput.

Usage

See the godoc page for full documentation.

import (
    "context"
    "fmt"
    "time"

    "github.com/cyrusaf/ratelimit"
)

func ExampleErrGroup() {
	ctx := context.Background()
	start := time.Now()

	// Create ratelimited errgroup with max 10 executions per second
	eg, ctx := ratelimit.WithContext(ctx, 10)

	// Kick off 10 goroutines.
	for i := 0; i < 10; i++ {
		// Shadow i so that it can be used in concurrent goroutines without
		// future loop iterations changing its value.
		i := i
		eg.Go(func() error {
			fmt.Printf("%d: %s\n", i, time.Since(start).Round(time.Millisecond*10))
			return nil
		})
	}

	err := eg.Wait()
	if err != nil {
		panic(err)
	}

	// Output:
	// 0: 100ms
	// 1: 200ms
	// 2: 300ms
	// 3: 400ms
	// 4: 500ms
	// 5: 600ms
	// 6: 700ms
	// 7: 800ms
	// 8: 900ms
	// 9: 1s
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ErrGroup

type ErrGroup struct {
	// contains filtered or unexported fields
}

ErrGroup implements the errgroup.Group interface, but limits goroutines to a execute at a max throughput.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/cyrusaf/ratelimit"
)

func main() {
	ctx := context.Background()
	start := time.Now()

	// Create ratelimited errgroup with max 10 executions per second
	eg, ctx := ratelimit.WithContext(ctx, 10)

	// Kick off 10 goroutines.
	for i := 0; i < 10; i++ {
		// Shadow i so that it can be used in concurrent goroutines without
		// future loop iterations changing its value.
		i := i
		eg.Go(func() error {
			fmt.Printf("%d: %s\n", i, time.Since(start).Round(time.Millisecond*10))
			return nil
		})
	}

	err := eg.Wait()
	if err != nil {
		panic(err)
	}

}
Output:

0: 100ms
1: 200ms
2: 300ms
3: 400ms
4: 500ms
5: 600ms
6: 700ms
7: 800ms
8: 900ms
9: 1s

func WithContext

func WithContext(ctx context.Context, rps int) (*ErrGroup, context.Context)

WithContext initializes and returns a new RateLimiter

func (*ErrGroup) Go

func (e *ErrGroup) Go(fn func() error)

Go runs a new job as a goroutine. It will wait until the next available time so that the ratelimit is not exceeded.

func (*ErrGroup) Wait

func (e *ErrGroup) Wait() error

Wait will wait until all jobs are processed. Once Wait() is called, no more jobs can be added.

Jump to

Keyboard shortcuts

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