This topic created in 1833 days ago, the information mentioned may be changed or developed.
Supplement 1 · May 8, 2021
尝试封装之后的结果
```
func rawDownloadImage(resource string, client *http.Client, logPrefix string, saveNamePath string) error {
maxRequest := 20
var fgetResponse = func() (*http.Response, error) {
// response, err := http.Get(imagePath)
return client.Get(resource)
}
var flog = func(text string) {
logging.FLog.Infof("%s, %s", logPrefix, text)
}
for j := 0; j < maxRequest; j++ {
// 设置超时时间为 3 分钟
err := func() error {
resp, err := util.RepeatRequestWithLog(fgetResponse, 60, []int{502}, time.Second*3, flog)
if err != nil {
return err
}
if resp == nil {
log.Fatalf("%s, login resp is null, err:%v", logPrefix, err)
}
logging.FLog.Infof("%s, login code:%d, err:%v", logPrefix, resp.StatusCode, err)
// util.PanicIfNotNull(err)
if resp.Body != nil {
defer resp.Body.Close()
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
out, err := os.Create(saveNamePath)
if err != nil {
return err
}
_, err = io.Copy(out, bytes.NewReader(body))
if err != nil {
return err
}
logging.FLog.Infof("%s, complete save path:%s", logPrefix, saveNamePath)
// return nil
// return resp
return nil
}()
if err != nil {
if strings.Contains(err.Error(), "(Client.Timeout or context cancellation while reading body)") {
if j < maxRequest-1 {
continue
}
return err
}
if util.StringContainAny(err.Error(), "EOF", "read: connection reset by peer", "http: server closed idle connection") {
if j < maxRequest-1 {
flog(fmt.Sprintf("err:%s", err.Error()))
// 关闭 IdelConnections
client.CloseIdleConnections()
flog("close_idle_connections")
continue
}
return err
}
return err
}
break
} //
return nil
}
```
Supplement 2 · May 8, 2021
RepeatRequestWithLog 代码
```
func RepeatRequestWithLog(getResponse FGetResponse, maxCount int, retryCodeArr []int, duration time.Duration, flog func(text string)) (*http.Response, error) {
for i := 0; i < maxCount; i++ {
resp, err := getResponse()
if err != nil {
if strings.Contains(err.Error(), "(Client.Timeout or context cancellation while reading body)") || strings.Contains(err.Error(), "context deadline exceeded (Client.Timeout exceeded while awaiting headers)") ||
strings.Contains(err.Error(), " i/o timeout (Client.Timeout exceeded while awaiting headers)") ||
strings.Contains(err.Error(), " EOF") {
if i < maxCount-1 {
flog(fmt.Sprintf("sleep for index:%d, err:%s, max:%d", i, err.Error(), maxCount))
time.Sleep(duration)
continue
}
}
return resp, err
}
code := resp.StatusCode
isInRetryCode := false
for _, iterCode := range retryCodeArr {
if code == iterCode {
isInRetryCode = true
}
}
// should return
if !isInRetryCode {
return resp, nil
} else {
if resp != nil {
resp.Body.Close()
}
// logging.FLog.Infof("time sleep")
flog(fmt.Sprintf("sleep for index:%d", i))
time.Sleep(duration)
}
}
return nil, errors.New("should not reach here")
}
```