Improve performance of Create Firewall Rule code (#489)

* Multi-thread server lookup to increase perf for multiple subscriptions

* Use parallel execution for listsubscriptions
- Also refactored parallel execution code to be a bit more generic
This commit is contained in:
Kevin Cunnane
2017-10-11 11:14:47 -07:00
committed by GitHub
parent 4945aead96
commit eab9339c14
5 changed files with 104 additions and 48 deletions

View File

@@ -21,6 +21,7 @@ using System.Globalization;
using Microsoft.Rest.Azure;
using Microsoft.SqlTools.ResourceProvider.Core;
using System.Collections;
using System.Threading;
namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
{
@@ -269,27 +270,46 @@ namespace Microsoft.SqlTools.ResourceProvider.DefaultImpl
public async Task<IEnumerable<IAzureUserAccountSubscriptionContext>> GetSubscriptionContextsAsync(IAzureUserAccount userAccount)
{
List<IAzureUserAccountSubscriptionContext> contexts = new List<IAzureUserAccountSubscriptionContext>();
foreach (IAzureTenant tenant in userAccount.AllTenants)
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
ServiceResponse<IAzureUserAccountSubscriptionContext> response = await AzureUtil.ExecuteGetAzureResourceAsParallel(
userAccount, userAccount.AllTenants, string.Empty, CancellationToken.None, GetSubscriptionsForTentantAsync);
if (response.HasError)
{
AzureTenant azureTenant = tenant as AzureTenant;
if (azureTenant != null)
{
ServiceClientCredentials credentials = CreateCredentials(azureTenant);
using (SubscriptionClient client = new SubscriptionClient(_resourceManagementUri, credentials))
{
IEnumerable<Subscription> subs = await GetSubscriptionsAsync(client);
contexts.AddRange(subs.Select(sub =>
{
AzureSubscriptionIdentifier subId = new AzureSubscriptionIdentifier(userAccount, azureTenant.TenantId, sub.SubscriptionId, _resourceManagementUri);
AzureUserAccountSubscriptionContext context = new AzureUserAccountSubscriptionContext(subId, credentials);
return context;
}));
}
}
var ex = response.Errors.First();
throw new AzureResourceFailedException(
string.Format(CultureInfo.CurrentCulture, SR.AzureSubscriptionFailedErrorMessage, ex.Message));
}
contexts.AddRange(response.Data);
stopwatch.Stop();
TraceEvent(TraceEventType.Verbose, (int)TraceId.AzureResource, "Time taken to get all subscriptions was {0}ms", stopwatch.ElapsedMilliseconds.ToString());
return contexts;
}
private async Task<ServiceResponse<IAzureUserAccountSubscriptionContext>> GetSubscriptionsForTentantAsync(
IAzureUserAccount userAccount, IAzureTenant tenant, string lookupKey,
CancellationToken cancellationToken, CancellationToken internalCancellationToken)
{
AzureTenant azureTenant = tenant as AzureTenant;
if (azureTenant != null)
{
ServiceClientCredentials credentials = CreateCredentials(azureTenant);
using (SubscriptionClient client = new SubscriptionClient(_resourceManagementUri, credentials))
{
IEnumerable<Subscription> subs = await GetSubscriptionsAsync(client);
return new ServiceResponse<IAzureUserAccountSubscriptionContext>(subs.Select(sub =>
{
AzureSubscriptionIdentifier subId = new AzureSubscriptionIdentifier(userAccount, azureTenant.TenantId, sub.SubscriptionId, _resourceManagementUri);
AzureUserAccountSubscriptionContext context = new AzureUserAccountSubscriptionContext(subId, credentials);
return context;
}));
}
}
return new ServiceResponse<IAzureUserAccountSubscriptionContext>();
}
/// <summary>
/// Returns the azure resource groups for given subscription
/// </summary>