Supplementary Go time packages providing production-ready rate limiting and occasional action execution utilities. This package implements a token bucket rate limiter for controlling event frequency and a Sometimes utility for executing actions at specified intervals.
go get golang.org/x/time@v0.14.0import "golang.org/x/time/rate"For specific functionality:
import (
"context"
"golang.org/x/time/rate"
"time"
)The most common pattern is using Wait to block until an action is allowed:
import (
"context"
"fmt"
"golang.org/x/time/rate"
)
func main() {
// Allow 10 requests per second with a burst of 5
limiter := rate.NewLimiter(10, 5)
// Wait blocks until the action is allowed
if err := limiter.Wait(context.Background()); err != nil {
fmt.Printf("Rate limit error: %v\n", err)
return
}
// Perform rate-limited action
fmt.Println("Action executed")
}Use Sometimes to execute an action periodically:
import (
"log"
"golang.org/x/time/rate"
"time"
)
var logger = rate.Sometimes{
First: 3, // Run first 3 times
Interval: 10 * time.Second, // Then every 10 seconds
}
func Spammy() {
// This will execute occasionally according to the rules
logger.Do(func() {
log.Println("Status update")
})
}Control the frequency of events using a token bucket algorithm. The rate limiter provides three approaches: non-blocking checks (Allow), reservation-based waiting (Reserve), and blocking waits (Wait). Supports dynamic rate and burst adjustments and is safe for concurrent use.
Key Types:
// Limit defines the maximum frequency of events (events per second)
type Limit float64
// Inf is the infinite rate limit
const Inf = Limit(math.MaxFloat64)
// NewLimiter creates a rate limiter with specified rate and burst
func NewLimiter(r Limit, b int) *Limiter
// Every converts a time interval to a rate limit
func Every(interval time.Duration) LimitCore Methods:
// Wait blocks until an event is allowed (most common)
func (lim *Limiter) Wait(ctx context.Context) (err error)
// Allow checks if an event can happen now without blocking
func (lim *Limiter) Allow() bool
// Reserve returns a reservation for a future event
func (lim *Limiter) Reserve() *ReservationRate Limiter - Complete API documentation with detailed examples
Execute actions occasionally based on configurable rules. The Sometimes utility provides flexible control over when actions execute using three filters (First, Every, Interval) applied as a union. Thread-safe for concurrent use.
Key Type:
type Sometimes struct {
First int // First N calls will run the action
Every int // Every Nth call will run the action
Interval time.Duration // Run if this duration has elapsed
}
func (s *Sometimes) Do(f func())Sometimes Utility - Complete API documentation with examples
The package is organized around two main components:
Rate Limiter (rate.Limiter): Implements the token bucket algorithm with three interaction patterns (Allow, Reserve, Wait) to handle different rate limiting scenarios. Maintains internal state including current token count, last update time, and rate parameters.
Sometimes Utility (rate.Sometimes): Provides a simple API for occasional action execution using configurable filters. Tracks call count and last execution time to determine when to run the provided function.
Both components are thread-safe and designed for concurrent use in production applications.