func()

in common/build.go [1452:1502]


func (b *Build) getStageTimeoutContexts(parent context.Context, timeouts ...stageTimeout) map[string]func() (context.Context, func()) {
	stack := make([]time.Duration, len(timeouts))

	deadline, hasDeadline := parent.Deadline()
	jobTimeout := time.Until(deadline)
	for idx, timeout := range timeouts {
		stack[idx] = timeout.defaultTimeout

		rawTimeout := b.GetAllVariables().Value(timeout.configName)
		duration, parseErr := time.ParseDuration(rawTimeout)

		switch {
		case strings.TrimSpace(rawTimeout) == "":
			// no-op

		case parseErr != nil:
			b.logger.Warningln(fmt.Sprintf("Ignoring malformed %s timeout: %v", timeout.configName, rawTimeout))

		case duration < 0:
			// no relative durations for now...
			b.logger.Warningln(fmt.Sprintf("Ignoring relative %s timeout: %v", timeout.configName, rawTimeout))

		case hasDeadline && duration > jobTimeout:
			// clamping timeouts to the job timeout happens automatically in `context.WithParent()`, mention it here
			b.logger.Warningln(fmt.Sprintf("%s timeout: %v is longer than job timeout. Setting to job timeout", timeout.configName, rawTimeout))

		case duration != 0:
			stack[idx] = duration
		}
	}

	results := make(map[string]func() (context.Context, func()))
	for idx, timeout := range timeouts {
		switch {
		case stack[idx] == 0:
			results[timeout.configName] = func() (context.Context, func()) {
				// no timeout
				return context.WithCancel(parent)
			}

		case stack[idx] > 0:
			duration := stack[idx]
			results[timeout.configName] = func() (context.Context, func()) {
				// absolute timeout
				return context.WithTimeout(parent, duration)
			}
		}
	}

	return results
}