Atlas › Test
TestErrorDependentPolicy
Exact test identity: go.temporal.io/server/common/backoff/TestRetryPolicySuite/TestErrorDependentPolicy
- Package
go.temporal.io/server/common/backoff
- Suite / test hierarchy
TestRetryPolicySuite/TestErrorDependentPolicy
- Test
TestErrorDependentPolicy
- Introduced at
- retrypolicy.go ×5 Frontier kind: Joint frontier
- Covered ranges
- 18
- Covered lines
- 90
- Covered files
- 2
Covered source
Expand a file to inspect source; the > gutter marks covered lines.
go.temporal.io/server/common/backoff/retrypolicy.go 60 covered LOC · 12 ranges
Open complete file
80
81
// NewExponentialRetryPolicy returns an instance of ExponentialRetryPolicy using the provided initialInterval
82
>
func NewExponentialRetryPolicy(initialInterval time.Duration) *ExponentialRetryPolicy {
retrypolicy.go
83
>
p := &ExponentialRetryPolicy{
84
>
initialInterval: initialInterval,
85
>
backoffCoefficient: defaultBackoffCoefficient,
86
>
maximumInterval: defaultMaximumInterval,
87
>
expirationInterval: defaultExpirationInterval,
88
>
maximumAttempts: defaultMaximumAttempts,
89
>
}
90
>
91
>
return p
92
>
}
93
94
// NewRetrier is used for creating a new instance of Retrier
95
>
func NewRetrier(policy RetryPolicy, timeSource clock.TimeSource) Retrier {
retrypolicy.go
96
>
return &retrierImpl{
97
>
policy: policy,
98
>
timeSource: timeSource,
99
>
startTime: timeSource.Now(),
100
>
currentAttempt: 1,
101
>
}
102
>
}
103
104
// WithInitialInterval sets the initial interval used by ExponentialRetryPolicy for the very first retry
121
// This does *not* cause the policy to stop retrying when the interval between retries reaches the supplied duration.
122
// That is what WithExpirationInterval does. Instead, this prevents the interval from exceeding maximumInterval.
123
>
func (p *ExponentialRetryPolicy) WithMaximumInterval(maximumInterval time.Duration) *ExponentialRetryPolicy {
retrypolicy.go
124
>
p.maximumInterval = maximumInterval
125
>
return p
126
>
}
127
128
// WithExpirationInterval sets the absolute expiration interval for all retries
129
>
func (p *ExponentialRetryPolicy) WithExpirationInterval(expirationInterval time.Duration) *ExponentialRetryPolicy {
retrypolicy.go
130
>
p.expirationInterval = expirationInterval
131
>
return p
132
>
}
133
134
// WithMaximumAttempts sets the maximum number of retry attempts
225
226
// NextBackOff returns the next delay interval. This is used by Retry to delay calling the operation again
227
>
func (r *retrierImpl) NextBackOff(err error) time.Duration {
retrypolicy.go
228
>
nextInterval := r.policy.ComputeNextDelay(r.getElapsedTime(), r.currentAttempt, err)
229
>
230
>
// Now increment the current attempt
231
>
r.currentAttempt++
232
>
return nextInterval
233
>
}
234
235
>
func (r *retrierImpl) getElapsedTime() time.Duration {
retrypolicy.go
236
>
return r.timeSource.Now().Sub(r.startTime)
237
>
}
238
239
var _ RetryPolicy = (*ErrorDependentRetryPolicy)(nil)
240
241
>
func NewErrorDependentRetryPolicy(delayForError func(err error) time.Duration) *ErrorDependentRetryPolicy {
retrypolicy.go
242
>
return &ErrorDependentRetryPolicy{
243
>
maximumAttempts: defaultMaximumAttempts,
244
>
delayForError: delayForError,
245
>
jitterPct: defaultJitterPct,
246
>
}
247
>
}
248
249
>
func (p *ErrorDependentRetryPolicy) WithMaximumAttempts(maximumAttempts int) *ErrorDependentRetryPolicy {
retrypolicy.go
250
>
p.maximumAttempts = maximumAttempts
251
>
return p
252
>
}
253
254
>
func (p *ErrorDependentRetryPolicy) WithJitter(jitterPct float64) *ErrorDependentRetryPolicy {
retrypolicy.go
255
>
p.jitterPct = jitterPct
256
>
return p
257
>
}
258
259
>
func (p *ErrorDependentRetryPolicy) ComputeNextDelay(_ time.Duration, attempt int, err error) time.Duration {
retrypolicy.go
260
>
if p.maximumAttempts != noMaximumAttempts && attempt >= p.maximumAttempts {
261
>
return done
262
>
}
263
264
>
return addJitter(p.delayForError(err), p.jitterPct)
retrypolicy.go
265
}
266
293
}
294
295
>
func addJitter(duration time.Duration, jitterPct float64) time.Duration {
retrypolicy.go
296
>
return duration * time.Duration(1+jitterPct*rand.Float64())
297
>
}
298
299
func getJitterRand() *rand.Rand {
go.temporal.io/server/common/clock/event_time_source.go 30 covered LOC · 6 ranges
Open complete file
39
40
// NewEventTimeSource returns a EventTimeSource with the current time set to Unix zero: 1970-01-01 00:00:00 +0000 UTC.
42
>
return &EventTimeSource{
43
>
now: time.Unix(0, 0),
44
>
}
45
>
}
46
47
// Some clients depend on the fact that the runtime's timers do _not_ run synchronously.
55
56
// Now return the current time.
58
>
ts.mu.RLock()
59
>
defer ts.mu.RUnlock()
60
>
61
>
return ts.now
62
>
}
63
64
func (ts *EventTimeSource) Since(t time.Time) time.Duration {
106
// Update the fake current time. It returns the timeSource so that you can chain calls like this:
107
// timeSource := NewEventTimeSource().Update(time.Now())
109
>
ts.mu.Lock()
110
>
defer ts.mu.Unlock()
111
>
112
>
ts.now = now
113
>
ts.fireTimers()
114
>
return ts
115
>
}
116
117
// Advance the timer by the specified duration.
119
>
ts.mu.Lock()
120
>
defer ts.mu.Unlock()
121
>
122
>
ts.now = ts.now.Add(d)
123
>
ts.fireTimers()
124
>
}
125
126
// AdvanceNext advances to the next timer.
156
157
// fireTimers fires all timers that are ready.
159
>
n := 0
160
>
for _, t := range ts.timers {
161
if t.deadline.After(ts.now) {
162
ts.timers[n] = t