| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Threading;
- namespace Top.Api
- {
- /// <summary>
- /// 调用出错自动重试客户端。
- /// </summary>
- public class AutoRetryTopClient : DefaultTopClient
- {
- private static readonly TopException RETRY_FAIL = new TopException("sdk.retry-call-fail", "API调用重试失败");
- /// <summary>
- /// 单次请求的最大重试次数,默认值为3次。
- /// </summary>
- private int maxRetryCount = 3;
- /// <summary>
- /// 重试之前休眠时间,默认值为100毫秒。
- /// </summary>
- private int retryWaitTime = 100;
- /// <summary>
- /// 超过最大重试次数时是否抛出异常。
- /// </summary>
- private bool throwIfOverMaxRetry = false;
- /// <summary>
- /// 自定义重试错误码列表。
- /// </summary>
- private IDictionary<string, bool> retryErrorCodes;
- public AutoRetryTopClient(string serverUrl, string appKey, string appSecret)
- : base(serverUrl, appKey, appSecret)
- {
- }
- public AutoRetryTopClient(string serverUrl, string appKey, string appSecret, string format)
- : base(serverUrl, appKey, appSecret, format)
- {
- }
- public override T Execute<T>(ITopRequest<T> request)
- {
- return Execute<T>(request, null);
- }
- public override T Execute<T>(ITopRequest<T> request, string session)
- {
- return Execute<T>(request, session, DateTime.Now);
- }
- public override T Execute<T>(ITopRequest<T> request, string session, DateTime timestamp)
- {
- T rsp = null;
- TopException exp = null;
- for (int i = 0; i < maxRetryCount; i++)
- {
- if (i > 0)
- {
- if ((rsp != null && ((rsp.SubErrCode != null && rsp.SubErrCode.StartsWith("isp."))
- || (retryErrorCodes != null && retryErrorCodes.ContainsKey(rsp.SubErrCode)))) || exp != null)
- {
- Thread.Sleep(retryWaitTime);
- topLogger.Warn(BuildRetryLog(request.GetApiName(), request.GetParameters(), i));
- }
- else
- {
- break;
- }
- }
- try
- {
- rsp = base.Execute(request, session);
- if (rsp.IsError)
- {
- if (i == maxRetryCount && throwIfOverMaxRetry)
- {
- throw RETRY_FAIL;
- }
- }
- else
- {
- return rsp;
- }
- }
- catch (TopException e)
- {
- if (exp == null)
- {
- exp = e;
- }
- }
- }
- if (exp != null)
- {
- throw exp;
- }
- else
- {
- return rsp;
- }
- }
- public void SetMaxRetryCount(int maxRetryCount)
- {
- this.maxRetryCount = maxRetryCount;
- }
- public void SetRetryWaitTime(int retryWaitTime)
- {
- this.retryWaitTime = retryWaitTime;
- }
- public void SetThrowIfOverMaxRetry(bool throwIfOverMaxRetry)
- {
- this.throwIfOverMaxRetry = throwIfOverMaxRetry;
- }
- public void AddRetryErrorCode(string errorCode)
- {
- if (this.retryErrorCodes == null)
- {
- this.retryErrorCodes = new Dictionary<string, bool>();
- }
- this.retryErrorCodes.Add(errorCode, false);
- }
- private string BuildRetryLog(string apiName, IDictionary<string, string> parameters, int retryCount)
- {
- StringBuilder sb = new StringBuilder();
- sb.Append(apiName).Append(" retry call ").Append(retryCount);
- if (parameters.ContainsKey("fields"))
- {
- parameters.Remove("fields");
- }
- sb.Append(" times, parameters=").Append(parameters);
- return sb.ToString();
- }
- }
- }
|