Exemple #1
0
        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));
        }
Exemple #2
0
        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);
        }