簡體   English   中英

什么是在Servicestack JsonServiceClient Get方法上實現重試的最佳解決方案?

[英]Whats the best solution to implement retry on Servicestack JsonServiceClient Get method?

在我的項目中,我使用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);

我在JsonServiceClient上創建了包裝類並在那里實現了重試,但我想知道這種方法的最佳解決方案是什么。

我同意你的做法。 擴展JsonServiceClient並實現重試邏輯,這是可重用性和可維護性的最佳方法,前提是您已實現如下所示。

擴展JsonServiceClient

擴展JsonServiceClient以便您可以合並自己的重試邏輯。 然后,您可以輕松地在代碼中重復使用, while無需在每次要求時使用while和counter。

如果你在這里看到JsonServiceClientBase.cs代碼,你會注意到所有動詞方法,如Get<TResponse> Post<TResponse> ... Put等都通過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替換對JsonServiceClientMyJsonServiceClientWithRetry
  • 設置嘗試次數
  • 正常使用客戶端。 (包含在try/catch塊中以在超過重試后捕獲異常)
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)
}

筆記:

如果拋出狀態代碼為400或401的WebServiceException我不會重試,因為在不更改它的情況下再次嘗試此請求似乎是多余的。 顯然你可以自定義這個邏輯。

如果連接超時,則會將超時錯誤作為WebException拋出。 如果您想特別處理此案例。

我希望有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM