Browse Source

implement timeout for singleton HttpClient #7618

pull/7619/head
Alper Ebicoglu 5 years ago
parent
commit
fa477b9e47
  1. 8
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Http/CliHttpClient.cs
  2. 51
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Http/CliHttpClientFactory.cs
  3. 101
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs
  4. 28
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs
  5. 23
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs

8
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Http/CliHttpClient.cs

@ -67,7 +67,12 @@ namespace Volo.Abp.Cli.Http
};
}
cancellationToken ??= CancellationToken.None;
if (cancellationToken == null)
{
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(DefaultTimeout);
cancellationToken = cancellationTokenSource.Token;
}
return await HttpPolicyExtensions
.HandleTransientHttpError()
@ -95,5 +100,6 @@ namespace Volo.Abp.Cli.Http
.ExecuteAsync(async () => await this.GetAsync(url, cancellationToken.Value));
}
}
}

51
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Http/CliHttpClientFactory.cs

@ -1,5 +1,7 @@
using System;
using System.Threading;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Cli.Http
{
@ -7,32 +9,67 @@ namespace Volo.Abp.Cli.Http
{
private static CliHttpClient _authenticatedHttpClient;
private static CliHttpClient _unauthenticatedHttpClient;
private readonly ICancellationTokenProvider _cancellationTokenProvider;
public CliHttpClient CreateClient(bool needsAuthentication = true)
public CliHttpClientFactory(ICancellationTokenProvider cancellationTokenProvider)
{
_cancellationTokenProvider = cancellationTokenProvider;
}
public CliHttpClient CreateClient(bool needsAuthentication = true, TimeSpan? timeout = null)
{
if (needsAuthentication)
{
return CreateAuthenticatedHttpClient();
return CreateAuthenticatedHttpClient(timeout);
}
return CreateUnAuthenticatedHttpClient();
return CreateUnAuthenticatedHttpClient(timeout);
}
public CancellationToken GetCancellationToken(TimeSpan? timeout = null)
{
if (timeout == null)
{
if (_cancellationTokenProvider == null)
{
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(CliHttpClient.DefaultTimeout);
return cancellationTokenSource.Token;
}
else
{
return _cancellationTokenProvider.Token;
}
}
else
{
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(Convert.ToInt32(timeout.Value.TotalMilliseconds));
return cancellationTokenSource.Token;
}
}
private static CliHttpClient CreateAuthenticatedHttpClient()
private static CliHttpClient CreateAuthenticatedHttpClient(TimeSpan? timeout = null)
{
if (_authenticatedHttpClient == null)
{
_authenticatedHttpClient = new CliHttpClient(setBearerToken: true);
_authenticatedHttpClient = new CliHttpClient(setBearerToken: true)
{
Timeout = System.Threading.Timeout.InfiniteTimeSpan
};
}
return _authenticatedHttpClient;
}
private static CliHttpClient CreateUnAuthenticatedHttpClient()
private static CliHttpClient CreateUnAuthenticatedHttpClient(TimeSpan? timeout = null)
{
if (_unauthenticatedHttpClient == null)
{
_unauthenticatedHttpClient = new CliHttpClient(setBearerToken: false);
_unauthenticatedHttpClient = new CliHttpClient(setBearerToken: false)
{
Timeout = System.Threading.Timeout.InfiniteTimeSpan
};
}
return _unauthenticatedHttpClient;

101
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs

@ -9,6 +9,7 @@ using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Cli.Http;
using Volo.Abp.Cli.ProjectBuilding.Templates.App;
@ -28,22 +29,23 @@ namespace Volo.Abp.Cli.ProjectBuilding
public ILogger<AbpIoSourceCodeStore> Logger { get; set; }
protected AbpCliOptions Options { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
private readonly CliHttpClientFactory _cliHttpClientFactory;
public AbpIoSourceCodeStore(
IOptions<AbpCliOptions> options,
IJsonSerializer jsonSerializer,
IRemoteServiceExceptionHandler remoteServiceExceptionHandler,
ICancellationTokenProvider cancellationTokenProvider)
ICancellationTokenProvider cancellationTokenProvider,
CliHttpClientFactory cliHttpClientFactory)
{
JsonSerializer = jsonSerializer;
RemoteServiceExceptionHandler = remoteServiceExceptionHandler;
CancellationTokenProvider = cancellationTokenProvider;
_cliHttpClientFactory = cliHttpClientFactory;
Options = options.Value;
Logger = NullLogger<AbpIoSourceCodeStore>.Instance;
@ -134,24 +136,17 @@ namespace Volo.Abp.Cli.ProjectBuilding
try
{
using (var client = new CliHttpClient(TimeSpan.FromMinutes(10)))
var client = _cliHttpClientFactory.CreateClient();
var stringContent = new StringContent(
JsonSerializer.Serialize(new GetLatestSourceCodeVersionDto { Name = name, IncludePreReleases = includePreReleases }),
Encoding.UTF8,
MimeTypes.Application.Json
);
using (var response = await client.PostAsync(url, stringContent, _cliHttpClientFactory.GetCancellationToken(TimeSpan.FromMinutes(10))))
{
var response = await client.PostAsync(
url,
new StringContent(
JsonSerializer.Serialize(
new GetLatestSourceCodeVersionDto { Name = name, IncludePreReleases = includePreReleases }
),
Encoding.UTF8,
MimeTypes.Application.Json
),
CancellationTokenProvider.Token
);
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response);
var result = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<GetVersionResultDto>(result).Version;
}
}
@ -164,32 +159,25 @@ namespace Volo.Abp.Cli.ProjectBuilding
private async Task<string> GetTemplateNugetVersionAsync(string name, string type, string version)
{
var url = $"{CliUrls.WwwAbpIo}api/download/{type}/get-nuget-version/";
try
{
using (var client = new CliHttpClient(TimeSpan.FromMinutes(10)))
{
var response = await client.PostAsync(
url,
new StringContent(
JsonSerializer.Serialize(
new GetTemplateNugetVersionDto { Name = name, Version = version}
),
Encoding.UTF8,
MimeTypes.Application.Json
),
CancellationTokenProvider.Token
);
var url = $"{CliUrls.WwwAbpIo}api/download/{type}/get-nuget-version/";
var client = _cliHttpClientFactory.CreateClient();
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response);
var stringContent = new StringContent(
JsonSerializer.Serialize(new GetTemplateNugetVersionDto { Name = name, Version = version }),
Encoding.UTF8,
MimeTypes.Application.Json
);
using (var response = await client.PostAsync(url, stringContent, _cliHttpClientFactory.GetCancellationToken(TimeSpan.FromMinutes(10))))
{
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response);
var result = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<GetVersionResultDto>(result).Version;
}
}
catch (Exception ex)
catch (Exception)
{
return null;
}
@ -203,36 +191,35 @@ namespace Volo.Abp.Cli.ProjectBuilding
try
{
using (var client = new CliHttpClient(TimeSpan.FromMinutes(10)))
{
var client = _cliHttpClientFactory.CreateClient();
if (input.TemplateSource.IsNullOrWhiteSpace())
{
responseMessage = await client.PostAsync(
url,
new StringContent(JsonSerializer.Serialize(input), Encoding.UTF8, MimeTypes.Application.Json),
CancellationTokenProvider.Token
);
}
else
{
responseMessage = await client.GetAsync(input.TemplateSource, CancellationTokenProvider.Token);
}
if (input.TemplateSource.IsNullOrWhiteSpace())
{
responseMessage = await client.PostAsync(
url,
new StringContent(JsonSerializer.Serialize(input), Encoding.UTF8, MimeTypes.Application.Json),
_cliHttpClientFactory.GetCancellationToken(TimeSpan.FromMinutes(10))
);
}
else
{
responseMessage = await client.GetAsync(input.TemplateSource, _cliHttpClientFactory.GetCancellationToken());
}
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage);
await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage);
var resultAsBytes = await responseMessage.Content.ReadAsByteArrayAsync();
responseMessage.Dispose();
return await responseMessage.Content.ReadAsByteArrayAsync();
}
return resultAsBytes;
}
catch (Exception ex)
{
Console.WriteLine("Error occured while downloading source-code from {0} : {1}{2}{3}",
url, responseMessage?.ToString(), Environment.NewLine, ex.Message);
Console.WriteLine("Error occured while downloading source-code from {0} : {1}{2}{3}", url, responseMessage?.ToString(), Environment.NewLine, ex.Message);
throw;
}
}
private bool IsNetworkSource(string source)
private static bool IsNetworkSource(string source)
{
return source.ToLower().StartsWith("http");
}

28
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/MyGetPackageListFinder.cs

@ -6,17 +6,23 @@ using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using Volo.Abp.Cli.Http;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Cli.ProjectModification
{
public class MyGetPackageListFinder : ISingletonDependency
{
private MyGetApiResponse _response;
public ILogger<MyGetPackageListFinder> Logger { get; set; }
public MyGetPackageListFinder()
private MyGetApiResponse _response;
private readonly CliHttpClientFactory _cliHttpClientFactory;
protected ICancellationTokenProvider CancellationTokenProvider { get; }
public MyGetPackageListFinder(CliHttpClientFactory cliHttpClientFactory,
ICancellationTokenProvider cancellationTokenProvider)
{
_cliHttpClientFactory = cliHttpClientFactory;
CancellationTokenProvider = cancellationTokenProvider;
Logger = NullLogger<MyGetPackageListFinder>.Instance;
}
@ -29,18 +35,20 @@ namespace Volo.Abp.Cli.ProjectModification
try
{
using (var client = new CliHttpClient(TimeSpan.FromMinutes(10)))
var client = _cliHttpClientFactory.CreateClient();
using (var responseMessage = await client.GetAsync(
$"{CliUrls.WwwAbpIo}api/myget/packages/",
_cliHttpClientFactory.GetCancellationToken(TimeSpan.FromMinutes(10))))
{
var responseMessage = await client.GetAsync(
$"{CliUrls.WwwAbpIo}api/myget/packages/"
_response = JsonConvert.DeserializeObject<MyGetApiResponse>(
Encoding.Default.GetString(await responseMessage.Content.ReadAsByteArrayAsync())
);
_response = JsonConvert.DeserializeObject<MyGetApiResponse>(Encoding.Default.GetString(await responseMessage.Content.ReadAsByteArrayAsync()));
}
}
catch (Exception)
catch (Exception ex)
{
Logger.LogError("Unable to get latest preview version.");
Logger.LogError("Unable to get latest preview version. Error: " + ex.Message);
throw;
}

23
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs

@ -27,15 +27,18 @@ namespace Volo.Abp.Cli.ProjectModification
private readonly PackageJsonFileFinder _packageJsonFileFinder;
private readonly NpmGlobalPackagesChecker _npmGlobalPackagesChecker;
private readonly Dictionary<string, string> _fileVersionStorage = new Dictionary<string, string>();
private readonly CliHttpClientFactory _cliHttpClientFactory;
public NpmPackagesUpdater(
PackageJsonFileFinder packageJsonFileFinder,
NpmGlobalPackagesChecker npmGlobalPackagesChecker,
ICancellationTokenProvider cancellationTokenProvider)
ICancellationTokenProvider cancellationTokenProvider,
CliHttpClientFactory cliHttpClientFactory)
{
_packageJsonFileFinder = packageJsonFileFinder;
_npmGlobalPackagesChecker = npmGlobalPackagesChecker;
CancellationTokenProvider = cancellationTokenProvider;
_cliHttpClientFactory = cliHttpClientFactory;
Logger = NullLogger<NpmPackagesUpdater>.Instance;
}
@ -151,16 +154,14 @@ namespace Volo.Abp.Cli.ProjectModification
{
try
{
using (var client = new CliHttpClient(TimeSpan.FromMinutes(1)))
var client = _cliHttpClientFactory.CreateClient();
using (var response = await client.GetHttpResponseMessageWithRetryAsync(
url: $"{CliUrls.WwwAbpIo}api/myget/apikey/",
cancellationToken: CancellationTokenProvider.Token,
logger: Logger
))
{
using (var response = await client.GetHttpResponseMessageWithRetryAsync(
url: $"{CliUrls.WwwAbpIo}api/myget/apikey/",
cancellationToken: CancellationTokenProvider.Token,
logger: Logger
))
{
return Encoding.Default.GetString(await response.Content.ReadAsByteArrayAsync());
}
return Encoding.Default.GetString(await response.Content.ReadAsByteArrayAsync());
}
}
catch (Exception)
@ -356,7 +357,7 @@ namespace Volo.Abp.Cli.ProjectModification
protected virtual string ExtractVersions(string output)
{
var arrayStart = output.IndexOf('[');
return output.Substring(arrayStart, output.IndexOf(']') - arrayStart + 1);
return output.Substring(arrayStart, output.IndexOf(']') - arrayStart + 1);
}
protected virtual bool SpecifiedVersionExists(string version, JProperty package)

Loading…
Cancel
Save