From b53e5f2b19eeb727621be9eb0fd808b4f7a42428 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Apr 2026 12:02:14 +0100 Subject: [PATCH] ax(mining): rename RateLimiter.mu to mutex; fix prose comment to usage example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AX Principle 1 (predictable names): `mu` abbreviates `mutex` — rename to `mutex`. AX Principle 2 (comments as usage examples): struct doc was prose ("provides token bucket rate limiting per IP address") — replace with concrete call examples. Co-Authored-By: Charon --- pkg/mining/ratelimiter.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pkg/mining/ratelimiter.go b/pkg/mining/ratelimiter.go index dd17d39..c4f13e1 100644 --- a/pkg/mining/ratelimiter.go +++ b/pkg/mining/ratelimiter.go @@ -8,12 +8,13 @@ import ( "github.com/gin-gonic/gin" ) -// RateLimiter provides token bucket rate limiting per IP address +// rl := NewRateLimiter(10, 20) // 10 req/s, burst 20 +// router.Use(rl.Middleware()) type RateLimiter struct { requestsPerSecond int burst int clients map[string]*rateLimitClient - mu sync.RWMutex + mutex sync.RWMutex stopChan chan struct{} stopped bool } @@ -56,8 +57,8 @@ func (rl *RateLimiter) cleanupLoop() { // rl.cleanup() // called every minute by cleanupLoop; evicts IPs idle for >5 minutes func (rl *RateLimiter) cleanup() { - rl.mu.Lock() - defer rl.mu.Unlock() + rl.mutex.Lock() + defer rl.mutex.Unlock() for ip, client := range rl.clients { if time.Since(client.lastCheck) > 5*time.Minute { @@ -68,8 +69,8 @@ func (rl *RateLimiter) cleanup() { // rl.Stop() // call on shutdown to release the cleanup goroutine func (rl *RateLimiter) Stop() { - rl.mu.Lock() - defer rl.mu.Unlock() + rl.mutex.Lock() + defer rl.mutex.Unlock() if !rl.stopped { close(rl.stopChan) @@ -82,7 +83,7 @@ func (rl *RateLimiter) Middleware() gin.HandlerFunc { return func(c *gin.Context) { ip := c.ClientIP() - rl.mu.Lock() + rl.mutex.Lock() client, exists := rl.clients[ip] if !exists { client = &rateLimitClient{tokens: float64(rl.burst), lastCheck: time.Now()} @@ -99,7 +100,7 @@ func (rl *RateLimiter) Middleware() gin.HandlerFunc { client.lastCheck = now if client.tokens < 1 { - rl.mu.Unlock() + rl.mutex.Unlock() respondWithError(c, http.StatusTooManyRequests, "RATE_LIMITED", "too many requests", "rate limit exceeded") c.Abort() @@ -107,14 +108,14 @@ func (rl *RateLimiter) Middleware() gin.HandlerFunc { } client.tokens-- - rl.mu.Unlock() + rl.mutex.Unlock() c.Next() } } // if rl.ClientCount() == 0 { /* no active clients */ } func (rl *RateLimiter) ClientCount() int { - rl.mu.RLock() - defer rl.mu.RUnlock() + rl.mutex.RLock() + defer rl.mutex.RUnlock() return len(rl.clients) }