package common import ( "errors" "net" "net/http" "time" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/utils" ) type AccessPlatformAPIWithRetryParams struct { MaxExceedLimitRetryCount int MaxRecoverableRetryCount int SleepSecondWhenExceedLimit time.Duration Client *http.Client Request *http.Request } const ( PAErrorLevelSuccess = "JXC4_SUCCESS" PAErrorLevelExceedLimit = "JXC4_EXCEED_LIMIT" PAErrorLevelRecoverable = "JXC4_RECOVERABLE" PAErrorLevelGeneralFail = "JXC4_GENERAL_FAIL" ) var ( ErrRecoverableErrMaxRetry = errors.New("recoverable error reach max retry count!") ErrLimitReachMaxRetry = errors.New("Reach max retry count!") ) var ( ErrStrHttpCode = "HTTP Code is not 200" ErrStrBusinessCode = "Business code is not ok" ) var ( CBErrMsgUnescape = "can not unescape data:%v, data:%v" CBErrMsgUnmarshal = "can not unmarshal data:%v, data:%v" ) func AccessPlatformAPIWithRetry(params *AccessPlatformAPIWithRetryParams, handleResponse func(response *http.Response) (string, error)) error { exceedLimitRetryCount := 0 recoverableErrorRetryCount := 0 for { response, err := params.Client.Do(params.Request) if err != nil { baseapi.SugarLogger.Debugf("client.Get return err:%v", err) err, ok := err.(net.Error) recoverableErrorRetryCount++ if ok && err.Timeout() && recoverableErrorRetryCount <= params.MaxRecoverableRetryCount { continue } else { return err } } defer response.Body.Close() if response.StatusCode != 200 { baseapi.SugarLogger.Debugf("http code is:%d", response.StatusCode) recoverableErrorRetryCount++ if recoverableErrorRetryCount <= params.MaxRecoverableRetryCount { continue } return utils.NewErrorIntCode(ErrStrHttpCode, response.StatusCode) } errCode, err := handleResponse(response) if err != nil { return err } if errCode == PAErrorLevelSuccess { return nil } else if errCode == PAErrorLevelExceedLimit { exceedLimitRetryCount++ if exceedLimitRetryCount <= params.MaxExceedLimitRetryCount { time.Sleep(params.SleepSecondWhenExceedLimit) } else { return ErrLimitReachMaxRetry } } else if errCode == PAErrorLevelRecoverable { if recoverableErrorRetryCount <= params.MaxRecoverableRetryCount { continue } return ErrRecoverableErrMaxRetry } else { return utils.NewErrorCode(ErrStrBusinessCode, errCode) } } }