go.temporal.io/server@v1.23.0/common/quotas/dynamic.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package quotas 26 27 import ( 28 "go.uber.org/atomic" 29 ) 30 31 type ( 32 // RateFn returns a float64 as the RPS 33 RateFn func() float64 34 35 // NamespaceRateFn returns a float64 as the RPS for the given namespace 36 NamespaceRateFn func(namespace string) float64 37 38 // BurstFn returns an int as the burst / bucket size 39 BurstFn func() int 40 41 // NamespaceBurstFn returns an int as the burst / bucket size for the given namespace 42 NamespaceBurstFn func(namespace string) float64 43 44 // RateBurst returns rate & burst for rate limiter 45 RateBurst interface { 46 Rate() float64 47 Burst() int 48 } 49 50 RateBurstImpl struct { 51 rateFn RateFn 52 burstFn BurstFn 53 } 54 55 // MutableRateBurstImpl stores the dynamic rate & burst for rate limiter 56 MutableRateBurstImpl struct { 57 rate *atomic.Float64 58 burst *atomic.Int64 59 } 60 61 MutableRateBurst interface { 62 SetRPS(rps float64) 63 SetBurst(burst int) 64 RateBurst 65 } 66 ) 67 68 func NewRateBurst( 69 rateFn RateFn, 70 burstFn BurstFn, 71 ) *RateBurstImpl { 72 return &RateBurstImpl{ 73 rateFn: rateFn, 74 burstFn: burstFn, 75 } 76 } 77 78 func NewDefaultIncomingRateBurst( 79 rateFn RateFn, 80 ) *RateBurstImpl { 81 return newDefaultRateBurst(rateFn, defaultIncomingRateBurstRatio) 82 } 83 84 func NewDefaultOutgoingRateBurst( 85 rateFn RateFn, 86 ) *RateBurstImpl { 87 return newDefaultRateBurst(rateFn, defaultOutgoingRateBurstRatio) 88 } 89 90 func newDefaultRateBurst( 91 rateFn RateFn, 92 rateToBurstRatio float64, 93 ) *RateBurstImpl { 94 burstFn := func() int { 95 rate := rateFn() 96 if rate < 0 { 97 rate = 0 98 } 99 if rateToBurstRatio < 0 { 100 rateToBurstRatio = 0 101 } 102 burst := int(rate * rateToBurstRatio) 103 if burst == 0 && rate > 0 && rateToBurstRatio > 0 { 104 burst = 1 105 } 106 return burst 107 } 108 return NewRateBurst(rateFn, burstFn) 109 } 110 111 func (d *RateBurstImpl) Rate() float64 { 112 return d.rateFn() 113 } 114 115 func (d *RateBurstImpl) Burst() int { 116 return d.burstFn() 117 } 118 119 func NewMutableRateBurst( 120 rate float64, 121 burst int, 122 ) *MutableRateBurstImpl { 123 return &MutableRateBurstImpl{ 124 rate: atomic.NewFloat64(rate), 125 burst: atomic.NewInt64(int64(burst)), 126 } 127 } 128 129 func (d *MutableRateBurstImpl) SetRPS(rate float64) { 130 d.rate.Store(rate) 131 } 132 133 func (d *MutableRateBurstImpl) SetBurst(burst int) { 134 d.burst.Store(int64(burst)) 135 } 136 137 func (d *MutableRateBurstImpl) Rate() float64 { 138 return d.rate.Load() 139 } 140 141 func (d *MutableRateBurstImpl) Burst() int { 142 return int(d.burst.Load()) 143 }