Files
funstat-mcp-go/internal/ratelimit/limiter.go
你的用户名 8d1ce4598d Initial commit: FunStat MCP Server Go implementation
- Telegram integration for customer statistics
- MCP server implementation with rate limiting
- Cache system for performance optimization
- Multi-language support
- RESTful API endpoints

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 15:28:06 +08:00

72 lines
1.1 KiB
Go

package ratelimit
import (
"context"
"sync"
"time"
)
type Limiter struct {
maxRequests int
window time.Duration
mu sync.Mutex
timestamps []time.Time
}
func New(maxRequests int, window time.Duration) *Limiter {
if maxRequests <= 0 {
maxRequests = 1
}
if window <= 0 {
window = time.Second
}
return &Limiter{
maxRequests: maxRequests,
window: window,
timestamps: make([]time.Time, 0, maxRequests),
}
}
func (l *Limiter) Wait(ctx context.Context) error {
for {
l.mu.Lock()
now := time.Now()
cutoff := now.Add(-l.window)
idx := 0
for ; idx < len(l.timestamps); idx++ {
if l.timestamps[idx].After(cutoff) {
break
}
}
if idx > 0 {
l.timestamps = append([]time.Time(nil), l.timestamps[idx:]...)
}
if len(l.timestamps) < l.maxRequests {
l.timestamps = append(l.timestamps, now)
l.mu.Unlock()
return nil
}
waitUntil := l.timestamps[0].Add(l.window)
waitDuration := time.Until(waitUntil)
l.mu.Unlock()
if waitDuration <= 0 {
continue
}
timer := time.NewTimer(waitDuration)
select {
case <-ctx.Done():
timer.Stop()
return ctx.Err()
case <-timer.C:
}
}
}