flightlimit

package module
v0.0.0-...-caf80b5 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2024 License: MIT Imports: 6 Imported by: 0

README

flightlimit

codecov GoDoc Go Report Card

flightlimit is an in-flight (concurrency) limiter using redis inspired by go-redis/redis_rate

GoDoc for usage

Basics

The normal workflow:

  1. an atomic redis roundtrip on takeoff Inc()
  2. check if result limit was hit or not, take action or go to #3
  3. normal processing
  4. land using a second atomic redis roundtrip Dec()

In case of errors the principle is "innocent before proven guilty", we Allow instead of block.

Flusher

The optional Flusher takes care of keys in incorrect state due to network or redis outtage. One example is if redis crashes after step #1, leaving the state of the counter in a stale state.

Example

// Miniredis server for testing
mr, _ := miniredis.Run()

// Setup Redis
ring := redis.NewRing(&redis.RingOptions{
    Addrs: map[string]string{"server0": mr.Addr()},
})

// Control max allowed time for flightlimit to block
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()

// Create a new flighlimiter
l := flightlimit.NewLimiter(ring, true)
defer l.Close()

// Allow a maximum of 10 in-flight, with expected processing time of <= 30 Seconds
limit := flightlimit.NewLimit(10, 30*time.Second)

// Mark as in-flight
r, _ := l.Inc(ctx, "foo:123", limit)

if !r.Allowed {
    //
    // Here a 429 could be returned
    //
    return
}

// Processing
fmt.Println(r.Remaining)

// Land
l.Decr(ctx, r)

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Limit

type Limit struct {
	// InFlight is the max number of InFlight before rate
	// limit hits and the Limiter return not Allowed in the Result.
	InFlight int64
	// Timeout should be above the expected max runtime for a request in flight.
	Timeout time.Duration
}

Limit instructions.

func NewLimit

func NewLimit(inflight int64, timeout time.Duration) *Limit

NewLimit creates a new Limit.

type Limiter

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

Limiter controls how frequently events are allowed to happen.

func NewLimiter

func NewLimiter(rdb rediser, enableflusher bool) *Limiter

NewLimiter returns a new Limiter.

Example
// Miniredis server
mr, _ := miniredis.Run()

// Setup Redis
ring := redis.NewRing(&redis.RingOptions{
	Addrs: map[string]string{"server0": mr.Addr()},
})

// Control max allowed time for flightlimit to block
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
defer cancel()

// Create a new flighlimiter
l := flightlimit.NewLimiter(ring, true)
defer l.Close()

// Allow a maximum of 10 in-flight, with expected processing time of <= 30 Seconds
limit := flightlimit.NewLimit(10, 30*time.Second)

// Mark as in-flight
r, _ := l.Inc(ctx, "foo:123", limit)

if !r.Allowed {
	//
	// Here a 429 could be returned
	//
	return
}

// Processing
fmt.Println(r.Remaining)

// Land
l.Decr(ctx, r)
Output:

9

func (*Limiter) Close

func (l *Limiter) Close()

Close the Limiter gracefully.

func (*Limiter) Decr

func (l *Limiter) Decr(ctx context.Context, r *Result) error

Decr decreases inflight value, closing the in-flight.

func (*Limiter) Inc

func (l *Limiter) Inc(ctx context.Context, key string, limit *Limit) (*Result, error)

Inc is shorthand for IncN(ctx, key, limit, 1).

func (*Limiter) IncDynamic

func (l *Limiter) IncDynamic(ctx context.Context, key string, limit *Limit, maxlimit int64) (*Result, error)

IncDynamic is shorthand for IncNDynamic(ctx, key, limit, 1, maxlimit).

func (*Limiter) IncN

func (l *Limiter) IncN(ctx context.Context, key string, limit *Limit, n int) (*Result, error)

IncN reports whether n events may happen at time now.

func (*Limiter) IncNDynamic

func (l *Limiter) IncNDynamic(ctx context.Context, key string, limit *Limit, n int, maxlimit int64) (*Result, error)

IncNDynamic reports whether n events may happen at time now with dynamic limit.

type Result

type Result struct {
	// Limit is the limit that was used to obtain this result.
	Limit *Limit

	// Allowed reports whether event may happen at time now.
	Allowed bool

	// Remaining is the maximum number of requests that could be
	// permitted instantaneously for this key given the current
	// state. For example, if a rate limiter allows 10 requests in
	// flight and has 6 mid air, Remaining would be 4.
	Remaining int64
	// contains filtered or unexported fields
}

Result is the obj we containing the result.

Jump to

Keyboard shortcuts

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