github.com/weaviate/weaviate@v1.24.6/entities/interval/backoff.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package interval 13 14 import ( 15 "sort" 16 "time" 17 ) 18 19 var defaultBackoffs = []time.Duration{ 20 time.Duration(0), 21 30 * time.Second, 22 2 * time.Minute, 23 10 * time.Minute, 24 1 * time.Hour, 25 12 * time.Hour, 26 } 27 28 // BackoffTimer tracks a given range of intervals with increasing duration 29 type BackoffTimer struct { 30 backoffLevel int 31 backoffs []time.Duration 32 lastInterval time.Time 33 } 34 35 // NewBackoffTimer constructs and returns a *BackoffTimer instance 36 // If no backoffs are provided, defaultBackoffs is used. When the 37 // last backoff duration has elapsed, the timer will use the final 38 // duration for the remainder of the BackoffTimer's lifetime 39 func NewBackoffTimer(backoffs ...time.Duration) *BackoffTimer { 40 boff := &BackoffTimer{backoffs: backoffs} 41 if len(backoffs) == 0 { 42 boff.backoffs = defaultBackoffs 43 } else { 44 sort.Slice(backoffs, func(i, j int) bool { 45 return backoffs[i] < backoffs[j] 46 }) 47 } 48 return boff 49 } 50 51 // IncreaseInterval bumps the duration of the interval up to the next given value 52 func (b *BackoffTimer) IncreaseInterval() { 53 b.lastInterval = time.Now() 54 if b.backoffLevel < len(b.backoffs) { 55 b.backoffLevel += 1 56 } 57 } 58 59 // IntervalElapsed returns if the current interval has elapsed 60 func (b *BackoffTimer) IntervalElapsed() bool { 61 return time.Since(b.lastInterval) > b.calculateInterval() 62 } 63 64 // Reset returns BackoffTimer to its original empty state 65 func (b *BackoffTimer) Reset() { 66 b.lastInterval = time.Time{} 67 b.backoffLevel = 0 68 } 69 70 func (b *BackoffTimer) calculateInterval() time.Duration { 71 if b.backoffLevel >= len(b.backoffs) { 72 return b.backoffs[len(b.backoffs)-1] 73 } 74 75 interval := b.backoffs[b.backoffLevel] 76 77 return interval 78 }