From fe05f52af6187ceed6e385a935a4a31c6279fe84 Mon Sep 17 00:00:00 2001 From: Sebastian Machuca Date: Thu, 1 Jan 2026 11:35:39 +1100 Subject: [PATCH] Rename package to accomodate to new changes --- {token => bucket}/registry.go | 6 ++--- {token => bucket}/registry_test.go | 30 +++++++++++----------- token/rate.go => bucket/token.go | 18 ++++++------- token/rate_test.go => bucket/token_test.go | 14 +++++----- 4 files changed, 34 insertions(+), 34 deletions(-) rename {token => bucket}/registry.go (84%) rename {token => bucket}/registry_test.go (79%) rename token/rate.go => bucket/token.go (75%) rename token/rate_test.go => bucket/token_test.go (90%) diff --git a/token/registry.go b/bucket/registry.go similarity index 84% rename from token/registry.go rename to bucket/registry.go index 31b42b8..049ce22 100644 --- a/token/registry.go +++ b/bucket/registry.go @@ -1,4 +1,4 @@ -package token +package bucket import ( "sync" @@ -8,13 +8,13 @@ type ( Identifier string Registry struct { mu sync.Mutex - limiters map[Identifier]*Limiter + limiters map[Identifier]*TokenLimiter capacity, rate uint32 } ) func NewRegistry(capacity, rate uint32, users ...Identifier) (*Registry, error) { - limiters := make(map[Identifier]*Limiter) + limiters := make(map[Identifier]*TokenLimiter) for _, user := range users { limiter := NewLimiter(capacity, rate) diff --git a/token/registry_test.go b/bucket/registry_test.go similarity index 79% rename from token/registry_test.go rename to bucket/registry_test.go index 78ee4b9..5604747 100644 --- a/token/registry_test.go +++ b/bucket/registry_test.go @@ -1,29 +1,29 @@ -package token_test +package bucket_test import ( "sync" "sync/atomic" "testing" - "github.com/serroba/rate/token" + "github.com/serroba/rate/bucket" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewRegistry(t *testing.T) { - reg, err := token.NewRegistry(10, 2) + reg, err := bucket.NewRegistry(10, 2) require.NoError(t, err) require.NotNil(t, reg) } func TestNewRegistry_WithUsers(t *testing.T) { - reg, err := token.NewRegistry(10, 2, "alice", "bob") + reg, err := bucket.NewRegistry(10, 2, "alice", "bob") require.NoError(t, err) require.NotNil(t, reg) } func TestRegistry_Allow_ExistingUser(t *testing.T) { - reg, err := token.NewRegistry(2, 0, "alice") + reg, err := bucket.NewRegistry(2, 0, "alice") require.NoError(t, err) require.True(t, reg.Allow("alice")) @@ -32,7 +32,7 @@ func TestRegistry_Allow_ExistingUser(t *testing.T) { } func TestRegistry_Allow_NewUser(t *testing.T) { - reg, err := token.NewRegistry(2, 0) + reg, err := bucket.NewRegistry(2, 0) require.NoError(t, err) // First call for a new user should create limiter and allow @@ -42,7 +42,7 @@ func TestRegistry_Allow_NewUser(t *testing.T) { } func TestRegistry_Allow_IndependentUsers(t *testing.T) { - reg, err := token.NewRegistry(1, 0) + reg, err := bucket.NewRegistry(1, 0) require.NoError(t, err) // Each user has their own bucket @@ -55,7 +55,7 @@ func TestRegistry_Allow_IndependentUsers(t *testing.T) { } func TestRegistry_Allow_Concurrent(t *testing.T) { - reg, err := token.NewRegistry(100, 0) + reg, err := bucket.NewRegistry(100, 0) require.NoError(t, err) var ( @@ -64,12 +64,12 @@ func TestRegistry_Allow_Concurrent(t *testing.T) { ) // 50 goroutines per user, 4 users = 200 goroutines - users := []token.Identifier{"alice", "bob", "charlie", "diana"} + users := []bucket.Identifier{"alice", "bob", "charlie", "diana"} for _, user := range users { for range 50 { wg.Add(1) - go func(u token.Identifier) { + go func(u bucket.Identifier) { defer wg.Done() if reg.Allow(u) { @@ -86,7 +86,7 @@ func TestRegistry_Allow_Concurrent(t *testing.T) { } func TestRegistry_Deny_Concurrent(t *testing.T) { - reg, err := token.NewRegistry(100, 0) + reg, err := bucket.NewRegistry(100, 0) require.NoError(t, err) var ( @@ -96,12 +96,12 @@ func TestRegistry_Deny_Concurrent(t *testing.T) { ) // 50 goroutines per user, 4 users = 200 goroutines - users := []token.Identifier{"alice", "bob", "charlie", "diana"} + users := []bucket.Identifier{"alice", "bob", "charlie", "diana"} for _, user := range users { for range 110 { wg.Add(1) - go func(u token.Identifier) { + go func(u bucket.Identifier) { defer wg.Done() if reg.Allow(u) { @@ -121,7 +121,7 @@ func TestRegistry_Deny_Concurrent(t *testing.T) { } func TestRegistry_Allow_ConcurrentNewUsers(t *testing.T) { - reg, err := token.NewRegistry(5, 0) + reg, err := bucket.NewRegistry(5, 0) require.NoError(t, err) var wg sync.WaitGroup @@ -133,7 +133,7 @@ func TestRegistry_Allow_ConcurrentNewUsers(t *testing.T) { go func(id int) { defer wg.Done() - user := token.Identifier(rune('a' + id%26)) + user := bucket.Identifier(rune('a' + id%26)) reg.Allow(user) }(i) } diff --git a/token/rate.go b/bucket/token.go similarity index 75% rename from token/rate.go rename to bucket/token.go index 1c716af..7c5994f 100644 --- a/token/rate.go +++ b/bucket/token.go @@ -1,4 +1,4 @@ -package token +package bucket import ( "sync" @@ -15,9 +15,9 @@ func (c realClock) Now() time.Time { return time.Now() } -// Limiter implements a token bucket rate limiter. It allows a burst of +// TokenLimiter implements a bucket rate limiter. It allows a burst of // requests up to capacity, then refills tokens at the specified rate per second. -type Limiter struct { +type TokenLimiter struct { mu sync.Mutex capacity, tokens, rate float64 lastRefillAt time.Time @@ -26,14 +26,14 @@ type Limiter struct { // NewLimiter creates a new rate limiter with the given capacity and refill rate. // Capacity is the maximum burst size. Rate is tokens added per second. -func NewLimiter(capacity, rate uint32) *Limiter { +func NewLimiter(capacity, rate uint32) *TokenLimiter { return NewLimiterWithClock(capacity, rate, realClock{}) } // NewLimiterWithClock creates a new rate limiter with a custom clock. // Use this constructor for testing with a mock clock. -func NewLimiterWithClock(capacity, rate uint32, clock clock) *Limiter { - return &Limiter{ +func NewLimiterWithClock(capacity, rate uint32, clock clock) *TokenLimiter { + return &TokenLimiter{ capacity: float64(capacity), tokens: float64(capacity), rate: float64(rate), @@ -42,10 +42,10 @@ func NewLimiterWithClock(capacity, rate uint32, clock clock) *Limiter { } } -// Allow reports whether a request is allowed. It consumes one token if +// Allow reports whether a request is allowed. It consumes one bucket if // available and returns true. If no tokens are available, it returns false // without blocking. -func (lim *Limiter) Allow() bool { +func (lim *TokenLimiter) Allow() bool { lim.mu.Lock() defer lim.mu.Unlock() @@ -60,7 +60,7 @@ func (lim *Limiter) Allow() bool { return false } -func (lim *Limiter) refill() { +func (lim *TokenLimiter) refill() { t := lim.clock.Now() if t.Before(lim.lastRefillAt) { return diff --git a/token/rate_test.go b/bucket/token_test.go similarity index 90% rename from token/rate_test.go rename to bucket/token_test.go index d954cb1..64c3f61 100644 --- a/token/rate_test.go +++ b/bucket/token_test.go @@ -1,4 +1,4 @@ -package token_test +package bucket_test import ( "sync" @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/serroba/rate/token" + "github.com/serroba/rate/bucket" "github.com/stretchr/testify/require" ) @@ -24,9 +24,9 @@ func (c *testClock) advance(by time.Duration) { func TestLimiter_Allow_ClockGoesBackwards(t *testing.T) { clock := &testClock{now: time.Now()} - lim := token.NewLimiterWithClock(1, 1, clock) + lim := bucket.NewLimiterWithClock(1, 1, clock) - // Drain the token + // Drain the bucket require.True(t, lim.Allow()) // Move clock backwards - should not refill @@ -74,7 +74,7 @@ func TestLimiter_Allow(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - lim := token.NewLimiterWithClock(tt.fields.capacity, tt.fields.rate, clock) + lim := bucket.NewLimiterWithClock(tt.fields.capacity, tt.fields.rate, clock) for range tt.previousAttempts { lim.Allow() @@ -90,7 +90,7 @@ func TestLimiter_Allow(t *testing.T) { } func TestLimiter_Allow_Concurrent(t *testing.T) { - lim := token.NewLimiter(100, 0) + lim := bucket.NewLimiter(100, 0) var ( allowed atomic.Int64 @@ -119,7 +119,7 @@ func TestLimiter_Allow_Concurrent(t *testing.T) { func TestLimiter_Allow_ConcurrentWithRefill(t *testing.T) { clock := &testClock{now: time.Now()} - lim := token.NewLimiterWithClock(10, 1000, clock) + lim := bucket.NewLimiterWithClock(10, 1000, clock) var ( allowed atomic.Int64