in retry.go [40:87]
func (w *Workflow) retry(opt *RetryOption) func(
ctx context.Context,
do func(context.Context) error,
notAfter time.Time, // the Step level timeout ddl
) error {
if opt == nil {
return func(ctx context.Context, do func(context.Context) error, notAfter time.Time) error { return do(ctx) }
}
return func(ctx context.Context, do func(context.Context) error, notAfter time.Time) error {
backOff := opt.Backoff
backOff = backoff.WithContext(backOff, ctx)
if !notAfter.IsZero() {
backOff = &backOffStopIfTimeout{BackOff: backOff, NotAfter: notAfter, Now: w.Clock.Now}
}
if opt.Attempts > 0 {
backOff = backoff.WithMaxRetries(backOff, opt.Attempts-1)
}
retried := func(ctx context.Context, e RetryEvent) {}
if opt.NextBackOff != nil {
b := &backOffWithEvent{BackOff: backOff, nextBackOff: opt.NextBackOff}
retried = b.retried
backOff = b
}
e := RetryEvent{Attempt: 0}
start := w.Clock.Now()
return backoff.RetryNotifyWithTimer(
func() error {
defer func() {
retried(ctx, e)
e.Attempt++
}()
ctxPerTry := ctx
if opt.TimeoutPerTry > 0 {
var cancel context.CancelFunc
ctxPerTry, cancel = w.Clock.WithTimeout(ctx, opt.TimeoutPerTry)
defer cancel()
}
err := do(ctxPerTry)
e.Since = w.Clock.Since(start)
e.Error = err
return err
},
backOff,
opt.Notify,
opt.Timer,
)
}
}