forked from concourse/concourse
/
retry_step.go
51 lines (41 loc) · 930 Bytes
/
retry_step.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package exec
import (
"context"
)
// RetryStep is a step that will run the steps in order until one of them
// succeeds.
type RetryStep struct {
Attempts []Step
LastAttempt Step
}
func Retry(attempts ...Step) Step {
return &RetryStep{
Attempts: attempts,
}
}
// Run iterates through each step, stopping once a step succeeds. If all steps
// fail, the RetryStep will fail.
func (step *RetryStep) Run(ctx context.Context, state RunState) error {
var attemptErr error
for _, attempt := range step.Attempts {
step.LastAttempt = attempt
attemptErr = attempt.Run(ctx, state)
if ctx.Err() != nil {
return ctx.Err()
}
if attemptErr != nil {
continue
}
if attempt.Succeeded() {
break
}
}
return attemptErr
}
// Succeeded delegates to the last step that it ran.
func (step *RetryStep) Succeeded() bool {
if step.LastAttempt == nil {
return false
}
return step.LastAttempt.Succeeded()
}