forked from vmware-archive/atc
/
timeout_step.go
53 lines (45 loc) · 1.19 KB
/
timeout_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
52
53
package exec
import (
"context"
"time"
)
// TimeoutStep applies a fixed timeout to a step's Run.
type TimeoutStep struct {
step Step
duration string
timedOut bool
}
// Timeout constructs a TimeoutStep factory.
func Timeout(step Step, duration string) *TimeoutStep {
return &TimeoutStep{
step: step,
duration: duration,
timedOut: false,
}
}
// Run parses the timeout duration and invokes the nested step.
//
// If the nested step takes longer than the duration, it is sent the Interrupt
// signal, and the TimeoutStep returns nil once the nested step exits (ignoring
// the nested step's error).
//
// The result of the nested step's Run is returned.
func (ts *TimeoutStep) Run(ctx context.Context, state RunState) error {
parsedDuration, err := time.ParseDuration(ts.duration)
if err != nil {
return err
}
timeoutCtx, cancel := context.WithTimeout(ctx, parsedDuration)
defer cancel()
err = ts.step.Run(timeoutCtx, state)
if err == context.DeadlineExceeded {
ts.timedOut = true
return nil
}
return err
}
// Succeeded is true if the nested step completed successfully
// and did not time out.
func (ts *TimeoutStep) Succeeded() bool {
return !ts.timedOut && ts.step.Succeeded()
}