github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/pkg/retry/retry.go (about) 1 // Copyright 2021 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package retry 15 16 import ( 17 "context" 18 "math" 19 "time" 20 21 "github.com/cenkalti/backoff" 22 "github.com/pingcap/errors" 23 ) 24 25 // Run is Deprecated, try to use Do instead. 26 // Run retries the specified function on error for at most maxRetries times. 27 // It stops retry if the returned error is context.Canceled or context.DeadlineExceeded. 28 func Run(initialInterval time.Duration, maxRetries uint64, f func() error) error { 29 cfg := backoff.NewExponentialBackOff() 30 cfg.InitialInterval = initialInterval 31 retryCfg := backoff.WithMaxRetries(cfg, maxRetries) 32 return backoff.Retry(func() error { 33 err := f() 34 switch errors.Cause(err) { 35 case context.Canceled, context.DeadlineExceeded: 36 err = backoff.Permanent(err) 37 } 38 return err 39 }, retryCfg) 40 } 41 42 // RunWithInfiniteRetry is Deprecated, try to use instead Do WithInfiniteTries option instead. 43 // RunWithInfiniteRetry retries the specified function indefinitely, until a backoff.PermanentError is encountered. 44 // notifyFunc will be called each time before sleeping with the total elapsed time. 45 func RunWithInfiniteRetry(initialInterval time.Duration, f func() error, notifyFunc func(elapsed time.Duration)) error { 46 cfg := backoff.NewExponentialBackOff() 47 cfg.InitialInterval = initialInterval 48 cfg.MaxElapsedTime = math.MaxInt64 49 50 startTime := time.Now() 51 err := backoff.Retry(func() error { 52 err := f() 53 switch errors.Cause(err) { 54 case context.Canceled, context.DeadlineExceeded: 55 err = backoff.Permanent(err) 56 } 57 58 if _, ok := err.(*backoff.PermanentError); !ok { 59 notifyFunc(time.Since(startTime)) 60 } 61 return err 62 }, cfg) 63 64 return err 65 }