mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-20 01:47:33 +00:00
.bencher
.github
atomicfile
chirp
client
cmd
control
derp
disco
docs
doctor
envknob
health
hostinfo
internal
ipn
jsondb
kube
licenses
log
logpolicy
logtail
metrics
net
packages
paths
portlist
prober
release
safesocket
scripts
smallzstd
ssh
syncs
tailcfg
tempfork
tka
tool
tsconst
tsnet
tstest
tstime
tsweb
types
dnstype
empty
flagtype
ipproto
key
lazy
logger
logger.go
logger_test.go
rusage.go
rusage_stub.go
rusage_syscall.go
tokenbucket.go
logid
netlogtype
netmap
nettype
opt
persist
preftype
ptr
structs
tkatype
views
util
version
wf
wgengine
words
.gitattributes
.gitignore
ALPINE.txt
AUTHORS
CODE_OF_CONDUCT.md
Dockerfile
Dockerfile.base
LICENSE
Makefile
PATENTS
README.md
SECURITY.md
VERSION.txt
api.md
build_dist.sh
build_docker.sh
flake.lock
flake.nix
go.mod
go.mod.sri
go.sum
go.toolchain.branch
go.toolchain.rev
pull-toolchain.sh
shell.nix
staticcheck.conf
update-flake.sh
version-embed.go
version_test.go
This updates all source files to use a new standard header for copyright and license declaration. Notably, copyright no longer includes a date, and we now use the standard SPDX-License-Identifier header. This commit was done almost entirely mechanically with perl, and then some minimal manual fixes. Updates #6865 Signed-off-by: Will Norris <will@tailscale.com>
64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package logger
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// tokenBucket is a simple token bucket style rate limiter.
|
|
|
|
// It's similar in function to golang.org/x/time/rate.Limiter, which we
|
|
// can't use because:
|
|
// - It doesn't give access to the number of accumulated tokens, which we
|
|
// need for implementing hysteresis;
|
|
// - It doesn't let us provide our own time function, which we need for
|
|
// implementing proper unit tests.
|
|
//
|
|
// rate.Limiter is also much more complex than necessary, but that wouldn't
|
|
// be enough to disqualify it on its own.
|
|
//
|
|
// Unlike rate.Limiter, this token bucket does not attempt to
|
|
// do any locking of its own. Don't try to access it reentrantly.
|
|
// That's fine inside this types/logger package because we already have
|
|
// locking at a higher level.
|
|
type tokenBucket struct {
|
|
remaining int
|
|
max int
|
|
tick time.Duration
|
|
t time.Time
|
|
}
|
|
|
|
func newTokenBucket(tick time.Duration, max int, now time.Time) *tokenBucket {
|
|
return &tokenBucket{max, max, tick, now}
|
|
}
|
|
|
|
func (tb *tokenBucket) Get() bool {
|
|
if tb.remaining > 0 {
|
|
tb.remaining--
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (tb *tokenBucket) Refund(n int) {
|
|
b := tb.remaining + n
|
|
if b > tb.max {
|
|
tb.remaining = tb.max
|
|
} else {
|
|
tb.remaining = b
|
|
}
|
|
}
|
|
|
|
func (tb *tokenBucket) AdvanceTo(t time.Time) {
|
|
diff := t.Sub(tb.t)
|
|
|
|
// only use up whole ticks. The remainder will be used up
|
|
// next time.
|
|
ticks := int(diff / tb.tick)
|
|
tb.t = tb.t.Add(time.Duration(ticks) * tb.tick)
|
|
|
|
tb.Refund(ticks)
|
|
}
|