github.com/crowdsecurity/crowdsec@v1.6.1/pkg/time/rate/rate.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package rate provides a rate limiter. 6 package rate 7 8 import ( 9 "context" 10 "fmt" 11 "math" 12 "sync" 13 "time" 14 ) 15 16 // Limit defines the maximum frequency of some events. 17 // Limit is represented as number of events per second. 18 // A zero Limit allows no events. 19 type Limit float64 20 21 // Inf is the infinite rate limit; it allows all events (even if burst is zero). 22 const Inf = Limit(math.MaxFloat64) 23 24 // Every converts a minimum time interval between events to a Limit. 25 func Every(interval time.Duration) Limit { 26 if interval <= 0 { 27 return Inf 28 } 29 return 1 / Limit(interval.Seconds()) 30 } 31 32 // A Limiter controls how frequently events are allowed to happen. 33 // It implements a "token bucket" of size b, initially full and refilled 34 // at rate r tokens per second. 35 // Informally, in any large enough time interval, the Limiter limits the 36 // rate to r tokens per second, with a maximum burst size of b events. 37 // As a special case, if r == Inf (the infinite rate), b is ignored. 38 // See https://en.wikipedia.org/wiki/Token_bucket for more about token buckets. 39 // 40 // The zero value is a valid Limiter, but it will reject all events. 41 // Use NewLimiter to create non-zero Limiters. 42 // 43 // Limiter has three main methods, Allow, Reserve, and Wait. 44 // Most callers should use Wait. 45 // 46 // Each of the three methods consumes a single token. 47 // They differ in their behavior when no token is available. 48 // If no token is available, Allow returns false. 49 // If no token is available, Reserve returns a reservation for a future token 50 // and the amount of time the caller must wait before using it. 51 // If no token is available, Wait blocks until one can be obtained 52 // or its associated context.Context is canceled. 53 // 54 // The methods AllowN, ReserveN, and WaitN consume n tokens. 55 type Limiter struct { 56 limit Limit 57 burst int 58 59 mu sync.Mutex 60 tokens float64 61 // last is the last time the limiter's tokens field was updated 62 last time.Time 63 // lastEvent is the latest time of a rate-limited event (past or future) 64 lastEvent time.Time 65 } 66 67 type RateLimiter interface { 68 Allow() bool 69 AllowN(time.Time, int) bool 70 GetTokensCount() float64 71 GetTokensCountAt(time.Time) float64 72 Dump() Lstate 73 Load(Lstate) 74 } 75 76 type Lstate struct { 77 Limit Limit 78 Burst int 79 Tokens float64 80 Last time.Time 81 LastEvent time.Time 82 } 83 84 func (lim *Limiter) Dump() Lstate { 85 st := Lstate{} 86 st.Limit = lim.limit 87 st.Burst = lim.burst 88 st.Tokens = lim.tokens 89 st.Last = lim.last 90 st.LastEvent = lim.lastEvent 91 return st 92 } 93 94 func (lim *Limiter) Load(st Lstate) { 95 lim.limit = st.Limit 96 lim.burst = st.Burst 97 lim.tokens = st.Tokens 98 lim.last = st.Last 99 lim.lastEvent = st.LastEvent 100 } 101 102 // Limit returns the maximum overall event rate. 103 func (lim *Limiter) Limit() Limit { 104 lim.mu.Lock() 105 defer lim.mu.Unlock() 106 return lim.limit 107 } 108 109 // Burst returns the maximum burst size. Burst is the maximum number of tokens 110 // that can be consumed in a single call to Allow, Reserve, or Wait, so higher 111 // Burst values allow more events to happen at once. 112 // A zero Burst allows no events, unless limit == Inf. 113 func (lim *Limiter) Burst() int { 114 return lim.burst 115 } 116 117 // NewLimiter returns a new Limiter that allows events up to rate r and permits 118 // bursts of at most b tokens. 119 func NewLimiter(r Limit, b int) *Limiter { 120 return &Limiter{ 121 limit: r, 122 burst: b, 123 } 124 } 125 126 // Allow is shorthand for AllowN(time.Now(), 1). 127 func (lim *Limiter) Allow() bool { 128 return lim.AllowN(time.Now(), 1) 129 } 130 131 // AllowN reports whether n events may happen at time now. 132 // Use this method if you intend to drop / skip events that exceed the rate limit. 133 // Otherwise use Reserve or Wait. 134 func (lim *Limiter) AllowN(now time.Time, n int) bool { 135 return lim.reserveN(now, n, 0).ok 136 } 137 138 // A Reservation holds information about events that are permitted by a Limiter to happen after a delay. 139 // A Reservation may be canceled, which may enable the Limiter to permit additional events. 140 type Reservation struct { 141 ok bool 142 lim *Limiter 143 tokens int 144 timeToAct time.Time 145 // This is the Limit at reservation time, it can change later. 146 limit Limit 147 } 148 149 // OK returns whether the limiter can provide the requested number of tokens 150 // within the maximum wait time. If OK is false, Delay returns InfDuration, and 151 // Cancel does nothing. 152 func (r *Reservation) OK() bool { 153 return r.ok 154 } 155 156 // Delay is shorthand for DelayFrom(time.Now()). 157 func (r *Reservation) Delay() time.Duration { 158 return r.DelayFrom(time.Now()) 159 } 160 161 // InfDuration is the duration returned by Delay when a Reservation is not OK. 162 const InfDuration = time.Duration(1<<63 - 1) 163 164 // DelayFrom returns the duration for which the reservation holder must wait 165 // before taking the reserved action. Zero duration means act immediately. 166 // InfDuration means the limiter cannot grant the tokens requested in this 167 // Reservation within the maximum wait time. 168 func (r *Reservation) DelayFrom(now time.Time) time.Duration { 169 if !r.ok { 170 return InfDuration 171 } 172 delay := r.timeToAct.Sub(now) 173 if delay < 0 { 174 return 0 175 } 176 return delay 177 } 178 179 // Cancel is shorthand for CancelAt(time.Now()). 180 func (r *Reservation) Cancel() { 181 r.CancelAt(time.Now()) 182 return 183 } 184 185 // CancelAt indicates that the reservation holder will not perform the reserved action 186 // and reverses the effects of this Reservation on the rate limit as much as possible, 187 // considering that other reservations may have already been made. 188 func (r *Reservation) CancelAt(now time.Time) { 189 if !r.ok { 190 return 191 } 192 193 r.lim.mu.Lock() 194 defer r.lim.mu.Unlock() 195 196 if r.lim.limit == Inf || r.tokens == 0 || r.timeToAct.Before(now) { 197 return 198 } 199 200 // calculate tokens to restore 201 // The duration between lim.lastEvent and r.timeToAct tells us how many tokens were reserved 202 // after r was obtained. These tokens should not be restored. 203 restoreTokens := float64(r.tokens) - r.limit.tokensFromDuration(r.lim.lastEvent.Sub(r.timeToAct)) 204 if restoreTokens <= 0 { 205 return 206 } 207 // advance time to now 208 now, _, tokens := r.lim.advance(now) 209 // calculate new number of tokens 210 tokens += restoreTokens 211 if burst := float64(r.lim.burst); tokens > burst { 212 tokens = burst 213 } 214 // update state 215 r.lim.last = now 216 r.lim.tokens = tokens 217 if r.timeToAct == r.lim.lastEvent { 218 prevEvent := r.timeToAct.Add(r.limit.durationFromTokens(float64(-r.tokens))) 219 if !prevEvent.Before(now) { 220 r.lim.lastEvent = prevEvent 221 } 222 } 223 224 return 225 } 226 227 // Reserve is shorthand for ReserveN(time.Now(), 1). 228 func (lim *Limiter) Reserve() *Reservation { 229 return lim.ReserveN(time.Now(), 1) 230 } 231 232 // ReserveN returns a Reservation that indicates how long the caller must wait before n events happen. 233 // The Limiter takes this Reservation into account when allowing future events. 234 // ReserveN returns false if n exceeds the Limiter's burst size. 235 // Usage example: 236 // r := lim.ReserveN(time.Now(), 1) 237 // if !r.OK() { 238 // // Not allowed to act! Did you remember to set lim.burst to be > 0 ? 239 // return 240 // } 241 // time.Sleep(r.Delay()) 242 // Act() 243 // Use this method if you wish to wait and slow down in accordance with the rate limit without dropping events. 244 // If you need to respect a deadline or cancel the delay, use Wait instead. 245 // To drop or skip events exceeding rate limit, use Allow instead. 246 func (lim *Limiter) ReserveN(now time.Time, n int) *Reservation { 247 r := lim.reserveN(now, n, InfDuration) 248 return &r 249 } 250 251 // Wait is shorthand for WaitN(ctx, 1). 252 func (lim *Limiter) Wait(ctx context.Context) (err error) { 253 return lim.WaitN(ctx, 1) 254 } 255 256 // WaitN blocks until lim permits n events to happen. 257 // It returns an error if n exceeds the Limiter's burst size, the Context is 258 // canceled, or the expected wait time exceeds the Context's Deadline. 259 // The burst limit is ignored if the rate limit is Inf. 260 func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) { 261 lim.mu.Lock() 262 burst := lim.burst 263 limit := lim.limit 264 lim.mu.Unlock() 265 266 if n > burst && limit != Inf { 267 return fmt.Errorf("rate: Wait(n=%d) exceeds limiter's burst %d", n, lim.burst) 268 } 269 // Check if ctx is already cancelled 270 select { 271 case <-ctx.Done(): 272 return ctx.Err() 273 default: 274 } 275 // Determine wait limit 276 now := time.Now() 277 waitLimit := InfDuration 278 if deadline, ok := ctx.Deadline(); ok { 279 waitLimit = deadline.Sub(now) 280 } 281 // Reserve 282 r := lim.reserveN(now, n, waitLimit) 283 if !r.ok { 284 return fmt.Errorf("rate: Wait(n=%d) would exceed context deadline", n) 285 } 286 // Wait if necessary 287 delay := r.DelayFrom(now) 288 if delay == 0 { 289 return nil 290 } 291 t := time.NewTimer(delay) 292 defer t.Stop() 293 select { 294 case <-t.C: 295 // We can proceed. 296 return nil 297 case <-ctx.Done(): 298 // Context was canceled before we could proceed. Cancel the 299 // reservation, which may permit other events to proceed sooner. 300 r.Cancel() 301 return ctx.Err() 302 } 303 } 304 305 // SetLimit is shorthand for SetLimitAt(time.Now(), newLimit). 306 func (lim *Limiter) SetLimit(newLimit Limit) { 307 lim.SetLimitAt(time.Now(), newLimit) 308 } 309 310 // SetLimitAt sets a new Limit for the limiter. The new Limit, and Burst, may be violated 311 // or underutilized by those which reserved (using Reserve or Wait) but did not yet act 312 // before SetLimitAt was called. 313 func (lim *Limiter) SetLimitAt(now time.Time, newLimit Limit) { 314 lim.mu.Lock() 315 defer lim.mu.Unlock() 316 317 now, _, tokens := lim.advance(now) 318 319 lim.last = now 320 lim.tokens = tokens 321 lim.limit = newLimit 322 } 323 324 // SetBurst is shorthand for SetBurstAt(time.Now(), newBurst). 325 func (lim *Limiter) SetBurst(newBurst int) { 326 lim.SetBurstAt(time.Now(), newBurst) 327 } 328 329 // SetBurstAt sets a new burst size for the limiter. 330 func (lim *Limiter) SetBurstAt(now time.Time, newBurst int) { 331 lim.mu.Lock() 332 defer lim.mu.Unlock() 333 334 now, _, tokens := lim.advance(now) 335 336 lim.last = now 337 lim.tokens = tokens 338 lim.burst = newBurst 339 } 340 341 // reserveN is a helper method for AllowN, ReserveN, and WaitN. 342 // maxFutureReserve specifies the maximum reservation wait duration allowed. 343 // reserveN returns Reservation, not *Reservation, to avoid allocation in AllowN and WaitN. 344 func (lim *Limiter) reserveN(now time.Time, n int, maxFutureReserve time.Duration) Reservation { 345 lim.mu.Lock() 346 347 if lim.limit == Inf { 348 lim.mu.Unlock() 349 return Reservation{ 350 ok: true, 351 lim: lim, 352 tokens: n, 353 timeToAct: now, 354 } 355 } 356 357 now, last, tokens := lim.advance(now) 358 359 // Calculate the remaining number of tokens resulting from the request. 360 tokens -= float64(n) 361 362 // Calculate the wait duration 363 var waitDuration time.Duration 364 if tokens < 0 { 365 waitDuration = lim.limit.durationFromTokens(-tokens) 366 } 367 368 // Decide result 369 ok := n <= lim.burst && waitDuration <= maxFutureReserve 370 371 // Prepare reservation 372 r := Reservation{ 373 ok: ok, 374 lim: lim, 375 limit: lim.limit, 376 } 377 if ok { 378 r.tokens = n 379 r.timeToAct = now.Add(waitDuration) 380 } 381 382 // Update state 383 if ok { 384 lim.last = now 385 lim.tokens = tokens 386 lim.lastEvent = r.timeToAct 387 } else { 388 lim.last = last 389 } 390 391 lim.mu.Unlock() 392 return r 393 } 394 395 // advance calculates and returns an updated state for lim resulting from the passage of time. 396 // lim is not changed. 397 func (lim *Limiter) advance(now time.Time) (newNow time.Time, newLast time.Time, newTokens float64) { 398 last := lim.last 399 if now.Before(last) { 400 last = now 401 } 402 403 // Avoid making delta overflow below when last is very old. 404 maxElapsed := lim.limit.durationFromTokens(float64(lim.burst) - lim.tokens) 405 elapsed := now.Sub(last) 406 if elapsed > maxElapsed { 407 elapsed = maxElapsed 408 } 409 410 // Calculate the new number of tokens, due to time that passed. 411 delta := lim.limit.tokensFromDuration(elapsed) 412 tokens := lim.tokens + delta 413 if burst := float64(lim.burst); tokens > burst { 414 tokens = burst 415 } 416 417 return now, last, tokens 418 } 419 420 // durationFromTokens is a unit conversion function from the number of tokens to the duration 421 // of time it takes to accumulate them at a rate of limit tokens per second. 422 func (limit Limit) durationFromTokens(tokens float64) time.Duration { 423 seconds := tokens / float64(limit) 424 return time.Nanosecond * time.Duration(1e9*seconds) 425 } 426 427 // tokensFromDuration is a unit conversion function from a time duration to the number of tokens 428 // which could be accumulated during that duration at a rate of limit tokens per second. 429 func (limit Limit) tokensFromDuration(d time.Duration) float64 { 430 // Split the integer and fractional parts ourself to minimize rounding errors. 431 // See golang.org/issues/34861. 432 sec := float64(d/time.Second) * float64(limit) 433 nsec := float64(d%time.Second) * float64(limit) 434 return sec + nsec/1e9 435 } 436 437 //return the number of token available in the bucket 438 func (lim *Limiter) GetTokensCount() float64 { 439 _, _, tokens := lim.advance(time.Now()) 440 return tokens 441 } 442 443 //return the number of token available in the bucket 444 func (lim *Limiter) GetTokensCountAt(t time.Time) float64 { 445 _, _, tokens := lim.advance(t) 446 return tokens 447 } 448 449 //A rate limiter that doesn't limit anything 450 //this is compliant to the earlier interface 451 type AlwaysFull struct { 452 } 453 454 func (af *AlwaysFull) Dump() Lstate { 455 return Lstate{} 456 } 457 458 func (af *AlwaysFull) Load(st Lstate) { 459 return 460 } 461 462 func (af *AlwaysFull) Allow() bool { 463 return true 464 } 465 466 func (af *AlwaysFull) AllowN(time.Time, int) bool { 467 return true 468 } 469 470 func (af *AlwaysFull) GetTokensCount() float64 { 471 return float64(int(^uint(0) >> 1)) 472 } 473 474 func (af *AlwaysFull) GetTokensCountAt(t time.Time) float64 { 475 return float64(int(^uint(0) >> 1)) 476 }