forked from apolloconfig/agollo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrequest.go
140 lines (118 loc) · 3.12 KB
/
request.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package http
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/xc407/agollo/v3/env/config"
"github.com/xc407/agollo/v3/loadbalance"
"github.com/xc407/agollo/v3/utils"
"github.com/xc407/agollo/v3/component/log"
"github.com/xc407/agollo/v3/env"
)
var (
//for on error retry
onErrorRetryInterval = 2 * time.Second //2s
connectTimeout = 1 * time.Second //1s
//max retries connect apollo
maxRetries = 5
)
//CallBack 请求回调函数
type CallBack struct {
SuccessCallBack func([]byte) (interface{}, error)
NotModifyCallBack func() error
}
//Request 建立网络请求
func Request(requestURL string, connectionConfig *env.ConnectConfig, callBack *CallBack) (interface{}, error) {
client := &http.Client{}
//如有设置自定义超时时间即使用
if connectionConfig != nil && connectionConfig.Timeout != 0 {
client.Timeout = connectionConfig.Timeout
} else {
client.Timeout = connectTimeout
}
retry := 0
var responseBody []byte
var err error
var res *http.Response
var retries = maxRetries
if connectionConfig != nil && !connectionConfig.IsRetry {
retries = 1
}
for {
retry++
if retry > retries {
break
}
res, err = client.Get(requestURL)
if res == nil || err != nil {
log.Error("Connect Apollo Server Fail,url:%s,Error:%s", requestURL, err)
// if error then sleep
time.Sleep(onErrorRetryInterval)
continue
}
//not modified break
switch res.StatusCode {
case http.StatusOK:
responseBody, err = ioutil.ReadAll(res.Body)
if err != nil {
log.Error("Connect Apollo Server Fail,url:%s,Error:", requestURL, err)
// if error then sleep
time.Sleep(onErrorRetryInterval)
continue
}
if callBack != nil && callBack.SuccessCallBack != nil {
return callBack.SuccessCallBack(responseBody)
}
return nil, nil
case http.StatusNotModified:
log.Info("Config Not Modified:", err)
if callBack != nil && callBack.NotModifyCallBack != nil {
return nil, callBack.NotModifyCallBack()
}
return nil, nil
default:
log.Error("Connect Apollo Server Fail,url:%s,StatusCode:%s", requestURL, res.StatusCode)
err = errors.New("connect Apollo Server Fail")
// if error then sleep
time.Sleep(onErrorRetryInterval)
continue
}
}
log.Error("Over Max Retry Still Error,Error:", err)
if err != nil {
err = errors.New("over Max Retry Still Error")
}
return nil, err
}
//RequestRecovery 可以恢复的请求
func RequestRecovery(appConfig *config.AppConfig,
connectConfig *env.ConnectConfig,
callBack *CallBack) (interface{}, error) {
format := "%s%s"
var err error
var response interface{}
for {
host := loadBalance(appConfig)
if host == "" {
return nil, err
}
requestURL := fmt.Sprintf(format, host, connectConfig.URI)
response, err = Request(requestURL, connectConfig, callBack)
if err == nil {
return response, err
}
env.SetDownNode(host)
}
}
func loadBalance(appConfig *config.AppConfig) string {
if !appConfig.IsConnectDirectly() {
return appConfig.GetHost()
}
serverInfo := loadbalance.GetLoadBalance().Load(env.GetServers())
if serverInfo == nil {
return utils.Empty
}
return serverInfo.HomepageURL
}