Skip to content

Commit b2bcf42

Browse files
committed
util: add retry mechanism
1 parent ba3f27f commit b2bcf42

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

util/retry.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package util
2+
3+
import (
4+
"context"
5+
"time"
6+
)
7+
8+
// RetryFunc is a function type that will try to be called again if it doesn't work
9+
type RetryFunc func() bool
10+
11+
// RetryCallbackFunc is a function type for callback
12+
type RetryCallbackFunc func()
13+
14+
// Retry is a wrapper function that is used to try to call external resources that have the potential to fail
15+
func Retry(ctx context.Context, n int, interval time.Duration,
16+
done chan<- bool, f RetryFunc, onSucceed RetryCallbackFunc, onError RetryCallbackFunc) {
17+
var i int = 1
18+
go func(ctx context.Context, i int, n int, interval time.Duration,
19+
done chan<- bool, f RetryFunc, onSucceed RetryCallbackFunc, onError RetryCallbackFunc) {
20+
21+
for {
22+
select {
23+
case <-ctx.Done():
24+
done <- true
25+
return
26+
default:
27+
}
28+
29+
succeed := f()
30+
if succeed {
31+
done <- true
32+
33+
if onSucceed != nil {
34+
onSucceed()
35+
}
36+
return
37+
}
38+
39+
if i == n {
40+
done <- true
41+
42+
if onError != nil {
43+
onError()
44+
}
45+
return
46+
}
47+
48+
<-time.After(interval)
49+
50+
i++
51+
52+
}
53+
}(ctx, i, n, interval, done, f, onSucceed, onError)
54+
}
55+
56+
// Usage
57+
58+
// func main() {
59+
// f := func() bool {
60+
// resp, err := httpPost("not_ok")
61+
// if err != nil {
62+
// fmt.Println(err)
63+
// return true
64+
// }
65+
66+
// statusOK := resp.httpCode >= 200 && resp.httpCode < 300
67+
// if !statusOK {
68+
// fmt.Println("retry")
69+
// return false
70+
// }
71+
72+
// return true
73+
// }
74+
75+
// done := make(chan bool, 1)
76+
77+
// ctx, cancel := context.WithCancel(context.Background())
78+
// //ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*500)
79+
// defer func() { cancel() }()
80+
81+
// onSucceed := func() {
82+
// fmt.Println("execution succeed")
83+
// }
84+
85+
// onError := func() {
86+
// fmt.Println("execution error")
87+
// }
88+
89+
// Retry(ctx, 5, 3*time.Second, done, f, onSucceed, onError)
90+
91+
// <-done
92+
93+
// //time.Sleep(time.Second * 15)
94+
// }
95+
96+
// type response struct {
97+
// httpCode int
98+
// }
99+
100+
// func httpPost(data string) (*response, error) {
101+
// if data == "fatal" {
102+
// return nil, errors.New("fatal error")
103+
// }
104+
105+
// if data == "not_ok" {
106+
// return &response{httpCode: 400}, nil
107+
// }
108+
109+
// return &response{httpCode: 200}, nil
110+
// }

0 commit comments

Comments
 (0)