Skip to content

Commit

Permalink
Merge pull request #107 from Archomeda/feature/add-connection-timeout
Browse files Browse the repository at this point in the history
Make request timeout configurable through IConnection
  • Loading branch information
Archomeda authored Nov 13, 2021
2 parents 9d8a454 + bd60d86 commit d196cf5
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 9 deletions.
7 changes: 7 additions & 0 deletions Gw2Sharp/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ public string AccessToken
/// <inheritdoc />
public string UserAgent { get; }

/// <inheritdoc />
public TimeSpan RequestTimeout
{
get => this.HttpClient.Timeout;
set => this.HttpClient.Timeout = value;
}

/// <inheritdoc />
public IHttpClient HttpClient
{
Expand Down
9 changes: 9 additions & 0 deletions Gw2Sharp/IConnection.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Gw2Sharp.WebApi;
using Gw2Sharp.WebApi.Caching;
using Gw2Sharp.WebApi.Http;
Expand Down Expand Up @@ -32,6 +33,14 @@ public interface IConnection
/// </summary>
string UserAgent { get; }

/// <summary>
/// Gets the request timeout that's used for the API requests.
/// If <see cref="TimeSpan.Zero"/> or less, the default timeout is used.
/// This value can be <see cref="Timeout.InfiniteTimeSpan"/> to have no timeout.
/// Defaults to the same value as <see cref="IHttpClient.Timeout"/> in <see cref="HttpClient"/>.
/// </summary>
TimeSpan RequestTimeout { get; }

/// <summary>
/// Gets the HTTP client that's used for the API requests.
/// </summary>
Expand Down
13 changes: 9 additions & 4 deletions Gw2Sharp/WebApi/Http/HttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public HttpClient(Func<SysHttpClient> getHttpClientFunc)
}

/// <inheritdoc />
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30);
public TimeSpan Timeout { get; set; } = TimeSpan.Zero;

/// <inheritdoc />
public async Task<IWebApiResponse> RequestAsync(IWebApiRequest request, CancellationToken cancellationToken = default)
Expand All @@ -67,8 +67,6 @@ public Task<IHttpResponseStream> RequestStreamAsync(IWebApiRequest request, Canc

async Task<IHttpResponseStream> ExecAsync()
{
using var cancellationTimeout = new CancellationTokenSource(this.Timeout);
using var linkedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancellationTimeout.Token);
using var message = new HttpRequestMessage(HttpMethod.Get, request.Options.Url);
message.Headers.AddRange(request.Options.RequestHeaders);

Expand All @@ -80,11 +78,18 @@ async Task<IHttpResponseStream> ExecAsync()
if (httpClient is null)
throw new InvalidOperationException("HttpClient is null");

task = httpClient.SendAsync(message, linkedCancellation.Token);
if (this.Timeout > TimeSpan.Zero || this.Timeout == System.Threading.Timeout.InfiniteTimeSpan)
httpClient.Timeout = this.Timeout;

task = httpClient.SendAsync(message, cancellationToken);
var responseMessage = await task.ConfigureAwait(false);

await responseMessage.Content.LoadIntoBufferAsync().ConfigureAwait(false);
#if NET5_0_OR_GREATER
var stream = await responseMessage.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
#else
var stream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
#endif
var requestHeaders = request.Options.RequestHeaders.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
var responseHeaders = responseMessage.Headers.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.First());
responseHeaders.AddRange(responseMessage.Content.Headers.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.First()));
Expand Down
3 changes: 3 additions & 0 deletions Gw2Sharp/WebApi/Http/IHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public interface IHttpClient
{
/// <summary>
/// The timeout for every request.
/// If <see cref="TimeSpan.Zero"/> or less, the default timeout is used (in case of <see cref="System.Net.Http.HttpClient"/>,
/// this is 100 seconds; see <seealso cref="System.Net.Http.HttpClient.Timeout"/>).
/// This value can be <see cref="Timeout.InfiniteTimeSpan"/> to have no timeout.
/// </summary>
TimeSpan Timeout { get; set; }

Expand Down
13 changes: 8 additions & 5 deletions Gw2Sharp/WebApi/Render/Gw2WebApiRenderClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ private Task<CacheItem> DownloadToCacheAsync(string renderUrl, CancellationToken
using var memoryStream = new MemoryStream();
await response.ContentStream.CopyToAsync(memoryStream).ConfigureAwait(false);
#else
await using var memoryStream = new MemoryStream();
var memoryStream = new MemoryStream();
await using var _ = memoryStream.ConfigureAwait(false);
await response.ContentStream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
#endif
var responseInfo = new HttpResponseInfo(response.StatusCode, response.CacheState, response.ResponseHeaders);
Expand Down Expand Up @@ -78,8 +79,9 @@ async Task ExecAsync()
using var memoryStream = new MemoryStream(cacheItem.RawItem, false);
await memoryStream.CopyToAsync(targetStream).ConfigureAwait(false);
#else
await using var memoryStream = new MemoryStream(cacheItem.RawItem, false);
await memoryStream.CopyToAsync(targetStream, cancellationToken).ConfigureAwait(false);
var memoryStream = new MemoryStream(cacheItem.RawItem, false);
await using (memoryStream.ConfigureAwait(false))
await memoryStream.CopyToAsync(targetStream, cancellationToken).ConfigureAwait(false);
#endif
}
}
Expand Down Expand Up @@ -110,8 +112,9 @@ async Task<byte[]> ExecAsync()
using var memoryStream = new MemoryStream(cacheItem.RawItem, false);
return memoryStream.ToArray();
#else
await using var memoryStream = new MemoryStream(cacheItem.RawItem, false);
return memoryStream.ToArray();
var memoryStream = new MemoryStream(cacheItem.RawItem, false);
await using (memoryStream.ConfigureAwait(false))
return memoryStream.ToArray();
#endif
}
}
Expand Down

0 comments on commit d196cf5

Please sign in to comment.