mirror of
https://github.com/Sarsoo/Spotify.NET.git
synced 2024-12-23 06:36:26 +00:00
More docs regarding retry_handling
This commit is contained in:
parent
d31a9e4ea1
commit
7bc5015950
50
SpotifyAPI.Docs/docs/retry_handling.md
Normal file
50
SpotifyAPI.Docs/docs/retry_handling.md
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
id: retry_handling
|
||||
title: Retry Handling
|
||||
---
|
||||
|
||||
In [Error Handling](error_handling.md) we already found out that requests can fail. We provide a way to automatically retry requests via retry handlers. Note, by default no retries are performed.
|
||||
|
||||
```csharp
|
||||
var config = SpotifyClientConfig
|
||||
.CreateDefault()
|
||||
.WithRetryHandler(new YourCustomRetryHandler())
|
||||
```
|
||||
|
||||
[`IRetryHandler`](https://github.com/JohnnyCrazy/SpotifyAPI-NET/blob/master/SpotifyAPI.Web/Http/Interfaces/IRetryHandler.cs) only needs one function:
|
||||
|
||||
```csharp
|
||||
public class YourCustomRetryHandler : IRetryHandler
|
||||
{
|
||||
public Task<IResponse> HandleRetry(IRequest request, IResponse response, IRetryHandler.RetryFunc retry)
|
||||
{
|
||||
// request is the sent request and response the received response, obviously?
|
||||
|
||||
// don't retry:
|
||||
return response;
|
||||
|
||||
// retry once
|
||||
var newResponse = retry(request);
|
||||
return newResponse;
|
||||
|
||||
// use retry as often as you want, make sure to return a response
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## SimpleRetryHandler
|
||||
|
||||
A `SimpleRetryHandler` is included, which contains the following retry logic:
|
||||
|
||||
* Retries the (configurable) status codes: 500, 502, 503 and 429
|
||||
* `RetryAfter` - specifies the delay between retried calls
|
||||
* `RetryTimes` - specifies the maxiumum amount of performed retries per call
|
||||
* `TooManyRequestsConsumesARetry` - Whether a failure of type "Too Many Requests" should use up one of the retry attempts.
|
||||
|
||||
```csharp
|
||||
var config = SpotifyClientConfig
|
||||
.CreateDefault()
|
||||
.WithRetryHandler(new SimpleRetryHandler() { RetryAfter = TimeSpan.FromSeconds(1) });
|
||||
|
||||
var spotify = new SpotifyClient(config);
|
||||
```
|
@ -40,11 +40,6 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
{ to: 'news', label: 'News', position: 'left' },
|
||||
{
|
||||
href: 'https://www.nuget.org/packages/SpotifyAPI.Web/',
|
||||
label: 'NuGET',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/JohnnyCrazy/SpotifyAPI-NET',
|
||||
label: 'GitHub',
|
||||
|
@ -12,6 +12,7 @@ module.exports = {
|
||||
'logging',
|
||||
'proxy',
|
||||
'pagination',
|
||||
'retry_handling',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -93,7 +93,25 @@ function Home() {
|
||||
<h1 className="hero__title">
|
||||
{siteConfig.title}
|
||||
<span style={{ marginLeft: '50px' }} />
|
||||
<GitHubButton href="https://github.com/JohnnyCrazy/SpotifyAPI-NET" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star JohnnyCrazy/SpotifyAPI-NET on GitHub">Star</GitHubButton>
|
||||
<GitHubButton
|
||||
href="https://github.com/JohnnyCrazy/SpotifyAPI-NET"
|
||||
data-icon="octicon-star"
|
||||
data-size="large"
|
||||
data-show-count="true"
|
||||
aria-label="Star JohnnyCrazy/SpotifyAPI-NET on GitHub">Star</GitHubButton>
|
||||
<br />
|
||||
<a href="https://www.nuget.org/packages/SpotifyAPI.Web/" rel="noopener noreferrer">
|
||||
<img
|
||||
alt="Nuget"
|
||||
src="https://img.shields.io/nuget/v/SpotifyAPI.Web?label=SpotifyAPI.Web&style=flat-square">
|
||||
</img>{' '}
|
||||
</a>
|
||||
<a href="https://www.nuget.org/packages/SpotifyAPI.Web.Auth/" rel="noopener noreferrer">
|
||||
<img
|
||||
alt="Nuget"
|
||||
src="https://img.shields.io/nuget/v/SpotifyAPI.Web.Auth?label=SpotifyAPI.Web.Auth&style=flat-square">
|
||||
</img>
|
||||
</a>
|
||||
</h1>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
<div className={styles.buttons}>
|
||||
|
@ -36,7 +36,7 @@ namespace SpotifyAPI.Web
|
||||
|
||||
Assert.AreEqual(2, retryCalled);
|
||||
Assert.AreEqual(setup.Response.Object, response);
|
||||
setup.Sleep.Verify(s => s(50000), Times.Exactly(2));
|
||||
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Exactly(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -67,7 +67,7 @@ namespace SpotifyAPI.Web
|
||||
|
||||
Assert.AreEqual(1, retryCalled);
|
||||
Assert.AreEqual(successResponse.Object, response);
|
||||
setup.Sleep.Verify(s => s(50000), Times.Once);
|
||||
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -97,7 +97,7 @@ namespace SpotifyAPI.Web
|
||||
|
||||
Assert.AreEqual(1, retryCalled);
|
||||
Assert.AreEqual(successResponse.Object, response);
|
||||
setup.Sleep.Verify(s => s(50000), Times.Once);
|
||||
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -117,13 +117,13 @@ namespace SpotifyAPI.Web
|
||||
{
|
||||
TooManyRequestsConsumesARetry = true,
|
||||
RetryTimes = 10,
|
||||
RetryAfter = 50
|
||||
RetryAfter = TimeSpan.FromMilliseconds(50)
|
||||
};
|
||||
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
|
||||
|
||||
Assert.AreEqual(10, retryCalled);
|
||||
Assert.AreEqual(setup.Response.Object, response);
|
||||
setup.Sleep.Verify(s => s(50), Times.Exactly(10));
|
||||
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Exactly(10));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -143,18 +143,18 @@ namespace SpotifyAPI.Web
|
||||
{
|
||||
TooManyRequestsConsumesARetry = true,
|
||||
RetryTimes = 10,
|
||||
RetryAfter = 50
|
||||
RetryAfter = TimeSpan.FromMilliseconds(50)
|
||||
};
|
||||
var response = await handler.HandleRetry(setup.Request.Object, setup.Response.Object, setup.Retry);
|
||||
|
||||
Assert.AreEqual(0, retryCalled);
|
||||
Assert.AreEqual(setup.Response.Object, response);
|
||||
setup.Sleep.Verify(s => s(50), Times.Exactly(0));
|
||||
setup.Sleep.Verify(s => s(TimeSpan.FromMilliseconds(50)), Times.Exactly(0));
|
||||
}
|
||||
|
||||
private class Setup
|
||||
{
|
||||
public Mock<Func<int, Task>> Sleep { get; set; } = new Mock<Func<int, Task>>();
|
||||
public Mock<Func<TimeSpan, Task>> Sleep { get; set; } = new Mock<Func<TimeSpan, Task>>();
|
||||
public Mock<IResponse> Response { get; set; } = new Mock<IResponse>();
|
||||
public Mock<IRequest> Request { get; set; } = new Mock<IRequest>();
|
||||
public IRetryHandler.RetryFunc Retry { get; set; }
|
||||
|
@ -9,12 +9,12 @@ namespace SpotifyAPI.Web
|
||||
{
|
||||
public class SimpleRetryHandler : IRetryHandler
|
||||
{
|
||||
private readonly Func<int, Task> _sleep;
|
||||
private readonly Func<TimeSpan, Task> _sleep;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies after how many miliseconds should a failed request be retried.
|
||||
/// </summary>
|
||||
public int RetryAfter { get; set; }
|
||||
public TimeSpan RetryAfter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of tries for one failed request.
|
||||
@ -38,10 +38,10 @@ namespace SpotifyAPI.Web
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public SimpleRetryHandler() : this(Task.Delay) { }
|
||||
public SimpleRetryHandler(Func<int, Task> sleep)
|
||||
public SimpleRetryHandler(Func<TimeSpan, Task> sleep)
|
||||
{
|
||||
_sleep = sleep;
|
||||
RetryAfter = 50;
|
||||
RetryAfter = TimeSpan.FromMilliseconds(50);
|
||||
RetryTimes = 10;
|
||||
TooManyRequestsConsumesARetry = false;
|
||||
RetryErrorCodes = new[] {
|
||||
@ -51,7 +51,7 @@ namespace SpotifyAPI.Web
|
||||
};
|
||||
}
|
||||
|
||||
private static int? ParseTooManyRetriesToMs(IResponse response)
|
||||
private static TimeSpan? ParseTooManyRetries(IResponse response)
|
||||
{
|
||||
if (response.StatusCode != (HttpStatusCode)429)
|
||||
{
|
||||
@ -59,7 +59,7 @@ namespace SpotifyAPI.Web
|
||||
}
|
||||
if (int.TryParse(response.Headers["Retry-After"], out int secondsToWait))
|
||||
{
|
||||
return secondsToWait * 1000;
|
||||
return TimeSpan.FromSeconds(secondsToWait);
|
||||
}
|
||||
|
||||
throw new APIException("429 received, but unable to parse Retry-After Header. This should not happen!");
|
||||
@ -78,7 +78,7 @@ namespace SpotifyAPI.Web
|
||||
IRetryHandler.RetryFunc retry,
|
||||
int triesLeft)
|
||||
{
|
||||
var secondsToWait = ParseTooManyRetriesToMs(response);
|
||||
var secondsToWait = ParseTooManyRetries(response);
|
||||
if (secondsToWait != null && (!TooManyRequestsConsumesARetry || triesLeft > 0))
|
||||
{
|
||||
await _sleep(secondsToWait.Value).ConfigureAwait(false);
|
||||
|
Loading…
Reference in New Issue
Block a user