什么是在Servicestack JsonServiceClient Get方法上实现重试的最佳解决方案?

时间:2015-03-18 03:51:43

标签: c# servicestack

在我的项目中,我使用Servicestack从特定URL获取数据,此过程是可配置的,我在单独的线程中调用获取数据,如果引发Timeout错误,我想实现重试。我在JsonServiceClient上创建了包装类并在那里实现了重试,但我想知道这种方法的最佳解决方案。

var _client = new JsonServiceClient { Timeout = timeout };
var counter = 0;
do
{
    try
    {
        result = _client.Get<TResponse>(url);
        break;
    }
    catch (Exception exp)
    {
        //Logging exception
    }
}
while (++counter < this.Retry);

1 个答案:

答案 0 :(得分:3)

  

我在JsonServiceClient上创建了包装类并在那里实现了重试,但我想知道这种方法的最佳解决方案是什么。

我同意你的做法。扩展JsonServiceClient并实现重试逻辑是可重用性和可维护性的最佳方法,前提是您已实现如下所示。

扩展JsonServiceClient

扩展JsonServiceClient,以便您可以合并自己的重试逻辑。然后,每次您想要发出请求时,都可以在代码中轻松重复使用while和计数器。

如果您在此处看到JsonServiceClientBase.cs代码,则会注意到所有动词方法,例如Get<TResponse> Post<TResponse> ... Put等都会通过{ {1}}方法。

因此,通过覆盖此方法,我们可以轻松地在所有动词上实现重试功能,而无需更改其用法。

Send<TResponse>(object request)

用法:

  • public class MyJsonServiceClientWithRetry : JsonServiceClient { public MyJsonServiceClientWithRetry() { } public MyJsonServiceClientWithRetry(int retryAttempts) { RetryAttempts = retryAttempts; } public MyJsonServiceClientWithRetry(string baseUri) : base(baseUri) { } public MyJsonServiceClientWithRetry(string syncReplyBaseUri, string asyncOneWayBaseUri) : base(syncReplyBaseUri, asyncOneWayBaseUri) { } // Retry attempts property public int RetryAttempts { get; set; } public override TResponse Send<TResponse> (string httpMethod, string relativeOrAbsoluteUrl, object request) { int attempts = RetryAttempts; while(true) { attempts--; try { return base.Send<TResponse> (httpMethod, relativeOrAbsoluteUrl, request); } catch (WebServiceException webException) { // Throw the exception if the number of retries is 0 or we have made a bad request, or are unauthenticated if(attempts == 0 || webException.StatusCode == 400 || webException.StatusCode == 401) throw; } catch (Exception exception) { // Throw the exception if the number of retries is 0 if(attempts == 0) throw; } } } } 的引用替换为JsonServiceClient
  • 设置尝试次数
  • 正常使用客户端。 (在MyJsonServiceClientWithRetry块中换行以在超过重试后捕获异常)
try/catch

注意:

如果使用状态代码400或401抛出var client = new MyJsonServiceClientWithRetry ("http://localhost:8080") { RetryAttempts = 3, Timeout = new TimeSpan(0, 0, 30) }; try { var myRequestDto = new MyRequest { Name = "John Smith" }; // This request will be attempted 3 times (if there is an exception) var response = client.Get<MyResponse>(myRequestDto); // Do something with response ... } catch(Exception ex) { // Exception thrown here after 3 attempts (or immediately if status code is 400 / 401) } ,我不会重试,因为在不更改它的情况下再次尝试此请求似乎是多余的。显然你可以自定义这个逻辑。

如果连接超时,则超时错误将被视为WebException。如果你想特别处理这个案子。

我希望有所帮助。