Atlas › Test

burst_refreshes_without_token_operation

Exact test identity: go.temporal.io/server/common/quotas/TestDynamicRateLimiterRateAndBurstRefreshAfterInterval/burst_refreshes_without_token_operation

Package
go.temporal.io/server/common/quotas
Suite / test hierarchy
TestDynamicRateLimiterRateAndBurstRefreshAfterInterval/burst_refreshes_without_token_operation
Test
burst_refreshes_without_token_operation
Introduced at
dynamic_rate_limiter_impl.go ×1 Frontier kind: Joint frontier
Covered ranges
26
Covered lines
102
Covered files
5

Covered source

Expand a file to inspect source; the > gutter marks covered lines.

go.temporal.io/server/common/quotas/rate_limiter_impl.go 40 covered LOC · 9 ranges

Open complete file

24 // NewRateLimiter returns a new rate limiter that can handle dynamic
25 // configuration updates
26 > func NewRateLimiter(newRPS float64, newBurst int) *RateLimiterImpl { rate_limiter_impl.go
27 > limiter := rate.NewLimiter(rate.Limit(newRPS), newBurst)
28 > ts := clock.NewRealTimeSource()
29 > rl := &RateLimiterImpl{
30 > rps: newRPS,
31 > burst: newBurst,
32 > timeSource: ts,
33 > ClockedRateLimiter: NewClockedRateLimiter(limiter, ts),
34 > }
35 >
36 > return rl
37 > }
38
39 // SetRPS sets the rate of the rate limiter
56
57 // SetRateBurst sets the rps & burst of the rate limiter
58 > func (rl *RateLimiterImpl) SetRateBurst(rps float64, burst int) { rate_limiter_impl.go
59 > rl.refreshInternalRateLimiterImpl(&rps, &burst)
60 > }
61
62 // Rate returns the rps for this rate limiter
69
70 // Burst returns the burst for this rate limiter
71 > func (rl *RateLimiterImpl) Burst() int { rate_limiter_impl.go
72 > rl.Lock()
73 > defer rl.Unlock()
74 >
75 > return rl.burst
76 > }
77
78 // TokensAt returns the number of tokens that will be available at time t
87 newRate *float64,
88 newBurst *int,
90 > rl.Lock()
91 > defer rl.Unlock()
92 >
93 > refresh := false
94 >
95 > if newRate != nil && rl.rps != *newRate {
96 > rl.rps = *newRate rate_limiter_impl.go
97 > refresh = true
98 > }
99
100 > if newBurst != nil && rl.burst != *newBurst { rate_limiter_impl.go
101 > rl.burst = *newBurst rate_limiter_impl.go
102 > refresh = true
103 > }
104
105 > if refresh { rate_limiter_impl.go
106 > now := rl.timeSource.Now() rate_limiter_impl.go
107 > rl.SetLimitAt(now, rate.Limit(rl.rps))
108 > rl.SetBurstAt(now, rl.burst)
109 > }
110 }
111
go.temporal.io/server/common/quotas/dynamic_rate_limiter_impl.go 23 covered LOC · 6 ranges

Open complete file

29 rateBurstFn RateBurst,
30 refreshInterval time.Duration,
31 > ) *DynamicRateLimiterImpl { dynamic_rate_limiter_impl.go
32 > rateLimiter := &DynamicRateLimiterImpl{
33 > rateBurstFn: rateBurstFn,
34 > refreshInterval: refreshInterval,
35 >
36 > refreshTimer: time.NewTimer(refreshInterval),
37 > rateLimiter: NewRateLimiter(rateBurstFn.Rate(), rateBurstFn.Burst()),
38 > }
39 > return rateLimiter
40 > }
41
42 // NewDefaultIncomingRateLimiter returns a default rate limiter
121
122 // Burst returns the burst for this rate limiter
123 > func (d *DynamicRateLimiterImpl) Burst() int { dynamic_rate_limiter_impl.go
124 > d.maybeRefresh()
125 > return d.rateLimiter.Burst()
126 > }
127
128 > func (d *DynamicRateLimiterImpl) Refresh() { dynamic_rate_limiter_impl.go
129 > d.rateLimiter.SetRateBurst(d.rateBurstFn.Rate(), d.rateBurstFn.Burst())
130 > }
131
132 > func (d *DynamicRateLimiterImpl) maybeRefresh() { dynamic_rate_limiter_impl.go
133 > select {
134 > case <-d.refreshTimer.C: dynamic_rate_limiter_impl.go
135 > d.refreshTimer.Reset(d.refreshInterval)
136 > d.Refresh()
137
139 // noop
140 }
go.temporal.io/server/common/quotas/rate_burst.go 19 covered LOC · 5 ranges

Open complete file

142 rate float64,
143 burst int,
144 > ) *MutableRateBurstImpl { rate_burst.go
145 > d := &MutableRateBurstImpl{}
146 > d.SetRPS(rate)
147 > d.SetBurst(burst)
148 >
149 > return d
150 > }
151
152 > func (d *MutableRateBurstImpl) SetRPS(rate float64) { rate_burst.go
153 > d.rate.Store(math.Float64bits(rate))
154 > }
155
156 > func (d *MutableRateBurstImpl) SetBurst(burst int) { rate_burst.go
157 > d.burst.Store(int64(burst))
158 > }
159
160 > func (d *MutableRateBurstImpl) Rate() float64 { rate_burst.go
161 > return math.Float64frombits(d.rate.Load())
162 > }
163
164 > func (d *MutableRateBurstImpl) Burst() int { rate_burst.go
165 > return int(d.burst.Load())
166 > }
167
168 func NewNamespaceRateBurst(
go.temporal.io/server/common/quotas/clocked_rate_limiter.go 14 covered LOC · 4 ranges

Open complete file

25 )
26
27 > func NewClockedRateLimiter(rateLimiter *rate.Limiter, timeSource clock.TimeSource) ClockedRateLimiter { clocked_rate_limiter.go
28 > return ClockedRateLimiter{
29 > rateLimiter: rateLimiter,
30 > timeSource: timeSource,
31 > recycleCh: make(chan struct{}),
32 > }
33 > }
34
35 func (l ClockedRateLimiter) Allow() bool {
142 }
143
144 > func (l ClockedRateLimiter) SetLimitAt(t time.Time, newLimit rate.Limit) { clocked_rate_limiter.go
145 > l.rateLimiter.SetLimitAt(t, newLimit)
146 > }
147
148 > func (l ClockedRateLimiter) SetBurstAt(t time.Time, newBurst int) { clocked_rate_limiter.go
149 > // Clamp burst to >=1 when rate is positive; burst=0 with rate=0 is allowed for pause.
150 > if newBurst < 1 && l.rateLimiter.Limit() > 0 {
151 newBurst = 1
152 }
153 > l.rateLimiter.SetBurstAt(t, newBurst) clocked_rate_limiter.go
154 }
155
go.temporal.io/server/common/clock/time_source.go 6 covered LOC · 2 ranges

Open complete file

31
32 // NewRealTimeSource returns a timeSource that uses the real wall timeSource time.
33 > func NewRealTimeSource() RealTimeSource { time_source.go
34 > return RealTimeSource{}
35 > }
36
37 // Now returns the current time, with the location set to UTC.
38 > func (ts RealTimeSource) Now() time.Time { time_source.go
39 > return time.Now().UTC()
40 > }
41
42 // Since returns the time elapsed since t