-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdoc.go
More file actions
147 lines (147 loc) · 4.21 KB
/
doc.go
File metadata and controls
147 lines (147 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Package ratelimit provides a flexible and extensible rate limiting library for Go applications.
//
// This package offers multiple rate limiting algorithms and storage backends to help
// control the rate of operations in your applications. It's designed to be thread-safe,
// context-aware, and suitable for both single-instance and distributed applications.
//
// # Features
//
// - Multiple rate limiting algorithms:
// - Fixed Window: Limits requests within a fixed time window
// - Token Bucket: Allows burst traffic while maintaining a long-term rate limit
// - No Limiter: A pass-through limiter that allows all operations (useful for testing)
//
// - Pluggable storage backends:
// - In-memory storage with automatic cleanup and configurable expiration
// - (More storage backends coming soon)
//
// - Thread-safe operations
// - Context-aware API with cancellation support
// - Distributed rate limiting support with mutex interface
//
// # Basic Usage
//
// Here's a simple example using a Fixed Window limiter:
//
// package main
//
// import (
// "context"
// "fmt"
// "time"
//
// "github.com/pioniro/rate-limit"
// "github.com/pioniro/rate-limit/policy"
// "github.com/pioniro/rate-limit/storage"
// )
//
// func main() {
// // Create an in-memory storage
// store := storage.NewInMemoryStorage()
//
// // Start the cleanup process
// ctx := context.Background()
// store.Start(ctx)
// defer store.Stop()
//
// // Create a fixed window rate limiter
// limiter, err := policy.NewFixedWindowLimiter(
// "login", // limiter ID
// 10, // limit (10 requests)
// 15*time.Minute, // interval (15 minutes)
// store, // storage backend
// )
// if err != nil {
// panic(err)
// }
//
// // Check if action is allowed
// key := "user123" // unique key for the entity being rate limited
// allowance, err := limiter.Allow(ctx, key, 1)
// if err != nil {
// panic(err)
// }
//
// if allowance.Allowed {
// fmt.Println("Request allowed")
// } else {
// fmt.Printf("Rate limit exceeded. Try again after %s\n",
// time.Until(allowance.Until))
// }
// }
//
// # Token Bucket Example
//
// The Token Bucket algorithm allows for burst traffic while maintaining a long-term rate:
//
// // Create a token bucket limiter with 100 tokens that refills at 10 tokens per second
// limiter, err := policy.NewTokenBucketLimiter(
// "api", // limiter ID
// 100, // burst size (max tokens)
// policy.PerSecond(10), // refill rate (10 tokens per second)
// store, // storage backend
// )
// if err != nil {
// panic(err)
// }
//
// // Consume 5 tokens
// allowed, err := limiter.Consume(ctx, "client1", 5)
// if err != nil {
// panic(err)
// }
//
// if allowed {
// // Process the request
// } else {
// // Rate limit exceeded
// }
//
// # No Limiter Example
//
// The NoLimiter is a pass-through limiter that allows all operations, useful for testing or conditional rate limiting:
//
// // Create a no-op limiter that allows all operations
// limiter := policy.NewNoLimiter()
//
// // This will always return true
// allowed, err := limiter.Consume(ctx, "any-key", 999999)
// if err != nil {
// panic(err)
// }
//
// // allowed will always be true
// fmt.Println("Allowed:", allowed)
//
// # Advanced Usage: Reservation
//
// For more control, you can use the Reserve method to get a reservation:
//
// reservation, err := limiter.Reserve(ctx, "client1", 10)
// if err != nil {
// panic(err)
// }
//
// // Check if tokens are immediately available
// if time.Now().After(reservation.Until) {
// // Process immediately
// } else {
// // Wait until tokens are available
// time.Sleep(time.Until(reservation.Until))
// // Now process the request
// }
//
// # Distributed Rate Limiting
//
// The package supports distributed rate limiting through the Storage interface.
// The built-in InMemoryStorage provides mutex-like functionality for single-instance
// applications, but you can implement your own Storage backend for distributed scenarios.
//
// # Thread Safety
//
// All operations in this package are thread-safe and can be used concurrently.
//
// # Context Support
//
// All methods accept a context.Context parameter, allowing for cancellation and timeouts.
package ratelimit