From adeeb7824d4f6cd7486044230185e10600dfb724 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Thu, 12 May 2016 22:39:21 -0400 Subject: [PATCH] Added a retry handler into the solution. We can now retry failed api requests. this should resolve #202 and start on #208 --- PlexRequests.Api/PlexApi.cs | 58 ++++++++++++++++--- PlexRequests.Api/PlexRequests.Api.csproj | 4 ++ PlexRequests.Api/RetryHandler.cs | 34 +++++++++++ PlexRequests.Api/packages.config | 1 + PlexRequests.UI/Validators/SonarrValidator.cs | 1 - 5 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 PlexRequests.Api/RetryHandler.cs diff --git a/PlexRequests.Api/PlexApi.cs b/PlexRequests.Api/PlexApi.cs index cbe06e3a6..5367cb267 100644 --- a/PlexRequests.Api/PlexApi.cs +++ b/PlexRequests.Api/PlexApi.cs @@ -23,6 +23,9 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ +using Polly; + + #endregion using System; @@ -67,7 +70,14 @@ namespace PlexRequests.Api request.AddJsonBody(userModel); var api = new ApiRequest(); - return api.Execute(request, new Uri("https://plex.tv/users/sign_in.json")); + + var policy = RetryHandler.RetryAndWaitPolicy (new TimeSpan[] { + TimeSpan.FromSeconds (2), + TimeSpan.FromSeconds(5), + TimeSpan.FromSeconds(10) + }, (exception, timespan) => Log.Error (exception, "Exception when calling SignIn for Plex, Retrying {0}", timespan)); + + return (PlexAuthentication)policy.Execute(() => api.Execute(request, new Uri("https://plex.tv/users/sign_in.json"))); } public PlexFriends GetUsers(string authToken) @@ -80,7 +90,13 @@ namespace PlexRequests.Api AddHeaders(ref request, authToken); var api = new ApiRequest(); - var users = api.ExecuteXml(request, new Uri("https://plex.tv/pms/friends/all")); + var policy = RetryHandler.RetryAndWaitPolicy (new TimeSpan[] { + TimeSpan.FromSeconds (2), + TimeSpan.FromSeconds(5), + TimeSpan.FromSeconds(10) + }, (exception, timespan) => Log.Error (exception, "Exception when calling GetUsers for Plex, Retrying {0}", timespan)); + + var users = (PlexFriends)policy.Execute(() =>api.ExecuteXml(request, new Uri("https://plex.tv/pms/friends/all"))); return users; } @@ -104,7 +120,13 @@ namespace PlexRequests.Api AddHeaders(ref request, authToken); var api = new ApiRequest(); - var search = api.ExecuteXml(request, plexFullHost); + var policy = RetryHandler.RetryAndWaitPolicy (new TimeSpan[] { + TimeSpan.FromSeconds (2), + TimeSpan.FromSeconds(5), + TimeSpan.FromSeconds(10) + }, (exception, timespan) => Log.Error (exception, "Exception when calling SearchContent for Plex, Retrying {0}", timespan)); + + var search = (PlexSearch)policy.Execute(() => api.ExecuteXml(request, plexFullHost)); return search; } @@ -117,9 +139,14 @@ namespace PlexRequests.Api }; AddHeaders(ref request, authToken); + var policy = RetryHandler.RetryAndWaitPolicy (new TimeSpan[] { + TimeSpan.FromSeconds (2), + TimeSpan.FromSeconds(5), + TimeSpan.FromSeconds(10) + }, (exception, timespan) => Log.Error (exception, "Exception when calling GetStatus for Plex, Retrying {0}", timespan)); var api = new ApiRequest(); - var users = api.ExecuteXml(request, uri); + var users = (PlexStatus)policy.Execute(() => api.ExecuteXml(request, uri)); return users; } @@ -133,8 +160,15 @@ namespace PlexRequests.Api AddHeaders(ref request, authToken); + var policy = RetryHandler.RetryAndWaitPolicy (new TimeSpan[] { + TimeSpan.FromSeconds (2), + TimeSpan.FromSeconds(5), + TimeSpan.FromSeconds(10) + }, (exception, timespan) => Log.Error (exception, "Exception when calling GetAccount for Plex, Retrying: {0}", timespan)); + + var api = new ApiRequest(); - var account = api.ExecuteXml(request, new Uri("https://plex.tv/users/account")); + var account = (PlexAccount)policy.Execute(() => api.ExecuteXml(request, new Uri("https://plex.tv/users/account"))); return account; } @@ -152,8 +186,13 @@ namespace PlexRequests.Api var api = new ApiRequest(); try { + var policy = RetryHandler.RetryAndWaitPolicy (new TimeSpan[] { + TimeSpan.FromSeconds (5), + TimeSpan.FromSeconds(10), + TimeSpan.FromSeconds(30) + }, (exception, timespan) => Log.Error (exception, "Exception when calling GetLibrarySections for Plex, Retrying {0}", timespan)); - return api.ExecuteXml(request, plexFullHost); + return (PlexLibraries)policy.Execute(() => api.ExecuteXml(request, plexFullHost)); } catch (ApiRequestException) { @@ -176,8 +215,13 @@ namespace PlexRequests.Api var api = new ApiRequest(); try { + var policy = RetryHandler.RetryAndWaitPolicy (new TimeSpan[] { + TimeSpan.FromSeconds (5), + TimeSpan.FromSeconds(10), + TimeSpan.FromSeconds(30) + }, (exception, timespan) => Log.Error (exception, "Exception when calling GetLibrary for Plex, Retrying {0}", timespan)); - return api.ExecuteXml(request, plexFullHost); + return (PlexSearch)policy.Execute(() => api.ExecuteXml(request, plexFullHost)); } catch (ApiRequestException) { diff --git a/PlexRequests.Api/PlexRequests.Api.csproj b/PlexRequests.Api/PlexRequests.Api.csproj index aa7db4a5b..a90f60f22 100644 --- a/PlexRequests.Api/PlexRequests.Api.csproj +++ b/PlexRequests.Api/PlexRequests.Api.csproj @@ -57,6 +57,9 @@ ..\packages\TMDbLib.0.9.0.0-alpha\lib\net45\TMDbLib.dll + + ..\packages\Polly-Signed.4.2.0\lib\net45\Polly.dll + @@ -81,6 +84,7 @@ + diff --git a/PlexRequests.Api/RetryHandler.cs b/PlexRequests.Api/RetryHandler.cs new file mode 100644 index 000000000..20267b228 --- /dev/null +++ b/PlexRequests.Api/RetryHandler.cs @@ -0,0 +1,34 @@ +using System; +using Polly.Retry; +using Polly; + +namespace PlexRequests.Api +{ + public static class RetryHandler + { + public static RetryPolicy RetryAndWaitPolicy(TimeSpan[] TimeSpan, Action action) + { + var policy = Policy.Handle () + .WaitAndRetry(TimeSpan, (exception, timeSpan) => action()); + + return policy; + } + + public static RetryPolicy RetryAndWaitPolicy(TimeSpan[] TimeSpan) + { + var policy = Policy.Handle () + .WaitAndRetry(TimeSpan); + + return policy; + } + + public static RetryPolicy RetryAndWaitPolicy(TimeSpan[] TimeSpan, Action action) + { + var policy = Policy.Handle () + .WaitAndRetry(TimeSpan, (exception, timeSpan) => action(exception, timeSpan)); + + return policy; + } + } +} + diff --git a/PlexRequests.Api/packages.config b/PlexRequests.Api/packages.config index 23ed979dc..5ebdcba2a 100644 --- a/PlexRequests.Api/packages.config +++ b/PlexRequests.Api/packages.config @@ -4,6 +4,7 @@ + \ No newline at end of file diff --git a/PlexRequests.UI/Validators/SonarrValidator.cs b/PlexRequests.UI/Validators/SonarrValidator.cs index e35eb654b..b252bd3b0 100644 --- a/PlexRequests.UI/Validators/SonarrValidator.cs +++ b/PlexRequests.UI/Validators/SonarrValidator.cs @@ -38,7 +38,6 @@ namespace PlexRequests.UI.Validators RuleFor(request => request.Ip).NotEmpty().WithMessage("You must specify a IP/Host name."); RuleFor(request => request.Port).NotEmpty().WithMessage("You must specify a Port."); RuleFor(request => request.QualityProfile).NotEmpty().WithMessage("You must specify a Quality Profile."); - RuleFor(request => request.RootPath).NotEmpty().WithMessage("You must specify a Root Path."); } } } \ No newline at end of file