protected T DoRequest <T>(object requestContent) { int retryCount = -1; ExponentialBackOff backOff = null; do { retryCount++; if (retryCount > 0) { // 等待一段时间再发起重试 if (backOff == null) { backOff = new ExponentialBackOff(250, 2.0, disConfig.GetBackOffMaxIntervalMs(), ExponentialBackOff.DEFAULT_MAX_ELAPSED_TIME); } backOff.backOff(backOff.getNextBackOff()); } try { requestObs.Headers.Remove(HttpHeaderKeys.Authorization); requestObs.Headers.Remove(HttpHeaderKeys.SdkData); requestObs.Headers.Remove(HttpHeaderKeys.SdkShaContent); requestObs.Headers.Remove(HttpHeaderKeys.HostHeader); // 每次重传需要重新签名 requestObs = SignUtil.Sign(requestObs, disConfig.GetAK(), disConfig.GetSK(), disConfig.GetRegion()); return(DoRequest <T>(requestObs, requestContent)); } catch (Exception t) { String errorMsg = t.Message; int statusCode = int.Parse(errorMsg.Split('\n')[0]); // 如果不是可以重试的异常 或者 已达到重试次数,则直接抛出异常 if (!Utils.Utils.IsRetriableSendException(statusCode) || retryCount >= disConfig.GetExceptionRetries()) { throw new Exception(errorMsg.Substring(statusCode.ToString().Length + 1), t); } logger.WarnFormat("Find Retriable Exception {0}, url [{1} {2}], currRetryCount is {3}", errorMsg.Replace("\r\n", ""), requestObs.HttpMethod, requestObs.Endpoint.Host.Trim('/') + requestObs.ResourcePath, retryCount); } } while (retryCount < disConfig.GetExceptionRetries()); return(default(T)); }
protected PutRecordsResult InnerPutRecordsWithRetry(PutRecordsRequest putRecordsParam, PutRecordMethod putRecordMethod) { //数据上传的结果集 PutRecordsResult putRecordsResult = null; //用该数组来汇总每次请求后的结果 PutRecordsResultEntry[] putRecordsResultEntryList = null; //记录每次请求失败的下标位置 int[] retryIndex = null; //每次需要上传的请求数据 PutRecordsRequest retryPutRecordsRequest = putRecordsParam; int retryCount = -1; int currentFailed = 0; ExponentialBackOff backOff = null; try { do { retryCount++; if (retryCount > 0) { // 等待一段时间再发起重试 if (backOff == null) { Monitor.Enter(objlock); logger.Info("Put records retry lock."); backOff = new ExponentialBackOff(ExponentialBackOff.DEFAULT_INITIAL_INTERVAL, ExponentialBackOff.DEFAULT_MULTIPLIER, _disConfig.GetBackOffMaxIntervalMs(), ExponentialBackOff.DEFAULT_MAX_ELAPSED_TIME); } if (putRecordsResult != null && currentFailed != putRecordsResult.Records.Count) { // 部分失败则重置退避时间 backOff.resetCurrentInterval(); } long sleepMs = backOff.getNextBackOff(); if (retryPutRecordsRequest.Records.Count > 0) { logger.DebugFormat( "Put {0} records but {1} failed, will re-try after backoff {2} ms, current retry count is {3}.", putRecordsResult != null ? putRecordsResult.Records.Count : putRecordsParam.Records.Count, currentFailed, sleepMs, retryCount); } backOff.backOff(sleepMs); } try { putRecordsResult = putRecordMethod(retryPutRecordsRequest); } catch (Exception t) { if (putRecordsResultEntryList != null) { logger.Error(t.Message, t); break; } throw t; } if (putRecordsResult != null) { currentFailed = putRecordsResult.FailedRecordCount; if (putRecordsResultEntryList == null && currentFailed == 0 || _disConfig.GetRecordsRetries() == 0) { // 第一次发送全部成功或者不需要重试,则直接返回结果 return(putRecordsResult); } if (putRecordsResultEntryList == null) { // 存在发送失败的情况,需要重试,则使用数组来汇总每次请求后的结果。 putRecordsResultEntryList = new PutRecordsResultEntry[putRecordsParam.Records.Count]; } // 需要重试发送数据的原始下标 List <int> retryIndexTemp = new List <int>(currentFailed); if (currentFailed > 0) { // 初始化重试发送的数据请求 retryPutRecordsRequest = new PutRecordsRequest(); retryPutRecordsRequest.StreamName = putRecordsParam.StreamName; retryPutRecordsRequest.Records = new List <PutRecordsRequestEntry>(currentFailed); } // 对每条结果分析,更新结果数据 for (int i = 0; i < putRecordsResult.Records.Count; i++) { // 获取重试数据在原始数据中的下标位置 int originalIndex = retryIndex == null ? i : retryIndex[i]; PutRecordsResultEntry putRecordsResultEntry = putRecordsResult.Records[i]; // 对所有异常进行重试 && "DIS.4303".equals(putRecordsResultEntry.getErrorCode()) if (!string.IsNullOrEmpty(putRecordsResultEntry.ErrorCode)) { retryIndexTemp.Add(originalIndex); retryPutRecordsRequest.Records.Add(putRecordsParam.Records[originalIndex]); } putRecordsResultEntryList[originalIndex] = putRecordsResultEntry; } retryIndex = retryIndexTemp.Count > 0 ? retryIndexTemp.ToArray() : new int[0]; } } while ((retryIndex == null || retryIndex.Length > 0) && retryCount < _disConfig.GetRecordsRetries()); } finally { if (retryCount > 0) { Monitor.Exit(objlock); logger.Info("Put records retry unlock."); } } putRecordsResult = new PutRecordsResult(); if (retryIndex == null) { // 不可能存在此情况,完全没有发送出去会直接抛出异常 putRecordsResult.FailedRecordCount = putRecordsParam.Records.Count; } else { putRecordsResult.FailedRecordCount = retryIndex.Length; putRecordsResult.Records = new List <PutRecordsResultEntry>(putRecordsResultEntryList); } return(putRecordsResult); }