Update dependencies
This commit is contained in:
90
vendor/tailscale.com/tstime/rate/rate.go
generated
vendored
Normal file
90
vendor/tailscale.com/tstime/rate/rate.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// This is a modified, simplified version of code from golang.org/x/time/rate.
|
||||
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package rate provides a rate limiter.
|
||||
package rate
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"tailscale.com/tstime/mono"
|
||||
)
|
||||
|
||||
// Limit defines the maximum frequency of some events.
|
||||
// Limit is represented as number of events per second.
|
||||
// A zero Limit is invalid.
|
||||
type Limit float64
|
||||
|
||||
// Every converts a minimum time interval between events to a Limit.
|
||||
func Every(interval time.Duration) Limit {
|
||||
if interval <= 0 {
|
||||
panic("invalid interval")
|
||||
}
|
||||
return 1 / Limit(interval.Seconds())
|
||||
}
|
||||
|
||||
// A Limiter controls how frequently events are allowed to happen.
|
||||
// It implements a [token bucket] of a particular size b,
|
||||
// initially full and refilled at rate r tokens per second.
|
||||
// Informally, in any large enough time interval,
|
||||
// the Limiter limits the rate to r tokens per second,
|
||||
// with a maximum burst size of b events.
|
||||
// Use NewLimiter to create non-zero Limiters.
|
||||
//
|
||||
// [token bucket]: https://en.wikipedia.org/wiki/Token_bucket
|
||||
type Limiter struct {
|
||||
limit Limit
|
||||
burst float64
|
||||
mu sync.Mutex // protects following fields
|
||||
tokens float64 // number of tokens currently in bucket
|
||||
last mono.Time // the last time the limiter's tokens field was updated
|
||||
}
|
||||
|
||||
// NewLimiter returns a new Limiter that allows events up to rate r and permits
|
||||
// bursts of at most b tokens.
|
||||
func NewLimiter(r Limit, b int) *Limiter {
|
||||
if b < 1 {
|
||||
panic("bad burst, must be at least 1")
|
||||
}
|
||||
return &Limiter{limit: r, burst: float64(b)}
|
||||
}
|
||||
|
||||
// Allow reports whether an event may happen now.
|
||||
func (lim *Limiter) Allow() bool {
|
||||
return lim.allow(mono.Now())
|
||||
}
|
||||
|
||||
func (lim *Limiter) allow(now mono.Time) bool {
|
||||
lim.mu.Lock()
|
||||
defer lim.mu.Unlock()
|
||||
|
||||
// If time has moved backwards, look around awkwardly and pretend nothing happened.
|
||||
if now.Before(lim.last) {
|
||||
lim.last = now
|
||||
}
|
||||
|
||||
// Calculate the new number of tokens available due to the passage of time.
|
||||
elapsed := now.Sub(lim.last)
|
||||
tokens := lim.tokens + float64(lim.limit)*elapsed.Seconds()
|
||||
if tokens > lim.burst {
|
||||
tokens = lim.burst
|
||||
}
|
||||
|
||||
// Consume a token.
|
||||
tokens--
|
||||
|
||||
// Update state.
|
||||
ok := tokens >= 0
|
||||
if ok {
|
||||
lim.last = now
|
||||
lim.tokens = tokens
|
||||
}
|
||||
return ok
|
||||
}
|
||||
Reference in New Issue
Block a user