- big big refactor.
This commit is contained in:
119
platformapi/platformapi.go
Normal file
119
platformapi/platformapi.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package platformapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
|
||||
"git.rosy.net.cn/baseapi"
|
||||
)
|
||||
|
||||
const (
|
||||
DefClientTimeout = 10 * time.Second
|
||||
DefSleepSecondWhenExceedLimit = 6 * time.Second
|
||||
DefMaxRecoverableRetryCount = 3
|
||||
DefMaxExceedLimitRetryCount = 10
|
||||
)
|
||||
|
||||
type APIRetryConfig struct {
|
||||
MaxExceedLimitRetryCount int
|
||||
MaxRecoverableRetryCount int
|
||||
SleepSecondWhenExceedLimit time.Duration
|
||||
}
|
||||
|
||||
type APIConfig struct {
|
||||
APIRetryConfig
|
||||
ClientTimeout time.Duration
|
||||
}
|
||||
|
||||
type AccessPlatformAPIWithRetryParam struct {
|
||||
APIRetryConfig
|
||||
Client *http.Client
|
||||
Request *http.Request
|
||||
}
|
||||
|
||||
var (
|
||||
DefAPIConfig = APIConfig{
|
||||
APIRetryConfig: APIRetryConfig{
|
||||
MaxExceedLimitRetryCount: DefMaxExceedLimitRetryCount,
|
||||
MaxRecoverableRetryCount: DefMaxRecoverableRetryCount,
|
||||
SleepSecondWhenExceedLimit: DefSleepSecondWhenExceedLimit,
|
||||
},
|
||||
ClientTimeout: DefClientTimeout,
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
ErrLevelSuccess = "JXC4_SUCCESS"
|
||||
ErrLevelExceedLimit = "JXC4_EXCEED_LIMIT"
|
||||
ErrLevelRecoverableErr = "JXC4_RECOVERABLE"
|
||||
ErrLevelGeneralFail = "JXC4_GENERAL_FAIL"
|
||||
ErrLevelCodeIsNotOK = "JXC4_CODE_IS_NOT_OK"
|
||||
)
|
||||
|
||||
// common api access error
|
||||
var (
|
||||
ErrAPIAccessFailed = errors.New("access API failed")
|
||||
ErrHTTPCodeIsNot200 = errors.New("HTTP code is not 200")
|
||||
ErrRecoverableErrReachMaxRetry = errors.New("recoverable error reach max retry count")
|
||||
ErrLimitExceedReachMaxRetry = errors.New("limit exceed reach max retry count")
|
||||
ErrResponseDataFormatWrong = errors.New("the data of response has wrong format")
|
||||
)
|
||||
|
||||
// common callback response
|
||||
var (
|
||||
ErrStrUnescapeError = "can not unescape data:%v, error:%v"
|
||||
ErrStrUnmarshalError = "can not unmarshal data:%v, error:%v"
|
||||
ErrStrCallbackSignatureIsWrong = "wrong signature"
|
||||
)
|
||||
|
||||
func init() {
|
||||
structs.DefaultTagName = "json"
|
||||
}
|
||||
|
||||
func AccessPlatformAPIWithRetry(client *http.Client, request *http.Request, config *APIConfig, handleResponse func(response *http.Response) (string, error)) error {
|
||||
exceedLimitRetryCount := 0
|
||||
recoverableErrorRetryCount := 0
|
||||
for {
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
baseapi.SugarLogger.Debugf("client.Get return err:%v", err)
|
||||
err, ok := err.(net.Error)
|
||||
recoverableErrorRetryCount++
|
||||
if ok && err.Timeout() && recoverableErrorRetryCount <= config.MaxRecoverableRetryCount {
|
||||
continue
|
||||
} else {
|
||||
baseapi.SugarLogger.Errorf("access api error:%v", err)
|
||||
return ErrAPIAccessFailed
|
||||
}
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode != 200 {
|
||||
baseapi.SugarLogger.Errorf("HTTP code not 200, it's:%v", response.StatusCode)
|
||||
return ErrHTTPCodeIsNot200
|
||||
}
|
||||
|
||||
errLevel, err := handleResponse(response)
|
||||
if err == nil {
|
||||
return nil
|
||||
} else if errLevel == ErrLevelExceedLimit {
|
||||
exceedLimitRetryCount++
|
||||
if exceedLimitRetryCount <= config.MaxExceedLimitRetryCount {
|
||||
time.Sleep(config.SleepSecondWhenExceedLimit)
|
||||
continue
|
||||
} else {
|
||||
return ErrLimitExceedReachMaxRetry
|
||||
}
|
||||
} else if errLevel == ErrLevelRecoverableErr {
|
||||
recoverableErrorRetryCount++
|
||||
if recoverableErrorRetryCount <= config.MaxRecoverableRetryCount {
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user