@@ -13,6 +13,8 @@ import (
13
13
14
14
clientv1 "github.com/qiniu/go-sdk/v7/client"
15
15
internal_io "github.com/qiniu/go-sdk/v7/internal/io"
16
+ "github.com/qiniu/go-sdk/v7/storagev2/chooser"
17
+ "github.com/qiniu/go-sdk/v7/storagev2/resolver"
16
18
)
17
19
18
20
type contextKeyBufferResponse struct {}
@@ -43,16 +45,44 @@ func (c *RetryConfig) init() {
43
45
}
44
46
}
45
47
46
- type simpleRetryInterceptor struct {
47
- config RetryConfig
48
- }
48
+ type (
49
+ SimpleRetryConfig struct {
50
+ RetryMax int // 最大重试次数
51
+ RetryInterval func () time.Duration // 重试时间间隔
52
+ ShouldRetry func (req * http.Request , resp * http.Response , err error ) bool
53
+ Resolver resolver.Resolver // 主备域名解析器
54
+ Chooser chooser.Chooser // 主备域名选择器
55
+ }
56
+
57
+ simpleRetryInterceptor struct {
58
+ config SimpleRetryConfig
59
+ }
60
+ )
61
+
62
+ func (c * SimpleRetryConfig ) init () {
63
+ if c == nil {
64
+ return
65
+ }
66
+
67
+ if c .RetryMax < 0 {
68
+ c .RetryMax = 0
69
+ }
70
+
71
+ if c .RetryInterval == nil {
72
+ c .RetryInterval = func () time.Duration {
73
+ return time .Duration (50 + rand .Int ()% 50 ) * time .Millisecond
74
+ }
75
+ }
49
76
50
- func NewSimpleRetryInterceptor (config RetryConfig ) Interceptor {
51
- return & simpleRetryInterceptor {
52
- config : config ,
77
+ if c .ShouldRetry == nil {
78
+ c .ShouldRetry = isSimpleRetryable
53
79
}
54
80
}
55
81
82
+ func NewSimpleRetryInterceptor (config SimpleRetryConfig ) Interceptor {
83
+ return & simpleRetryInterceptor {config : config }
84
+ }
85
+
56
86
func (interceptor * simpleRetryInterceptor ) Priority () InterceptorPriority {
57
87
return InterceptorPriorityRetrySimple
58
88
}
@@ -65,9 +95,18 @@ func (interceptor *simpleRetryInterceptor) Intercept(req *http.Request, handler
65
95
66
96
interceptor .config .init ()
67
97
68
- // 不重试
69
- if interceptor .config .RetryMax <= 0 {
70
- return handler (req )
98
+ var ips []net.IP
99
+ hostname := req .URL .Hostname ()
100
+
101
+ if resolver := interceptor .config .Resolver ; resolver != nil {
102
+ if ips , err = resolver .Resolve (req .Context (), hostname ); err == nil && len (ips ) > 0 {
103
+ if cs := interceptor .config .Chooser ; cs != nil {
104
+ ips = cs .Choose (req .Context (), & chooser.ChooseOptions {IPs : ips , Domain : hostname })
105
+ }
106
+ if len (ips ) > 0 {
107
+ req = req .WithContext (clientv1 .WithResolvedIPs (req .Context (), hostname , ips ))
108
+ }
109
+ }
71
110
}
72
111
73
112
// 可能会被重试多次
@@ -83,8 +122,19 @@ func (interceptor *simpleRetryInterceptor) Intercept(req *http.Request, handler
83
122
}
84
123
85
124
if ! interceptor .config .ShouldRetry (reqBefore , resp , err ) {
125
+ if len (ips ) > 0 {
126
+ if cs := interceptor .config .Chooser ; cs != nil {
127
+ cs .FeedbackGood (req .Context (), & chooser.FeedbackOptions {IPs : ips , Domain : hostname })
128
+ }
129
+ }
86
130
return resp , err
87
131
}
132
+ if len (ips ) > 0 {
133
+ if cs := interceptor .config .Chooser ; cs != nil {
134
+ cs .FeedbackBad (req .Context (), & chooser.FeedbackOptions {IPs : ips , Domain : hostname })
135
+ }
136
+ }
137
+
88
138
req = reqBefore
89
139
90
140
if i >= interceptor .config .RetryMax {
0 commit comments