github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/exec/timeout_step.go (about)

     1  package exec
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"time"
     7  )
     8  
     9  // TimeoutStep applies a fixed timeout to a step's Run.
    10  type TimeoutStep struct {
    11  	step     Step
    12  	duration string
    13  	timedOut bool
    14  }
    15  
    16  // Timeout constructs a TimeoutStep factory.
    17  func Timeout(step Step, duration string) *TimeoutStep {
    18  	return &TimeoutStep{
    19  		step:     step,
    20  		duration: duration,
    21  		timedOut: false,
    22  	}
    23  }
    24  
    25  // Run parses the timeout duration and invokes the nested step.
    26  //
    27  // If the nested step takes longer than the duration, it is sent the Interrupt
    28  // signal, and the TimeoutStep returns nil once the nested step exits (ignoring
    29  // the nested step's error).
    30  //
    31  // The result of the nested step's Run is returned.
    32  func (ts *TimeoutStep) Run(ctx context.Context, state RunState) (bool, error) {
    33  	parsedDuration, err := time.ParseDuration(ts.duration)
    34  	if err != nil {
    35  		return false, err
    36  	}
    37  
    38  	timeoutCtx, cancel := context.WithTimeout(ctx, parsedDuration)
    39  	defer cancel()
    40  
    41  	ok, err := ts.step.Run(timeoutCtx, state)
    42  	if errors.Is(err, context.DeadlineExceeded) {
    43  		return false, nil
    44  	}
    45  
    46  	return ok, err
    47  }