Browse Source

Initialize dynamic features.

pull/13881/head
maliming 4 years ago
parent
commit
00e165e7dd
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 133
      modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs

133
modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs

@ -1,8 +1,18 @@
using Volo.Abp.Caching;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Polly;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.FeatureManagement.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
namespace Volo.Abp.FeatureManagement;
@ -30,4 +40,125 @@ public class AbpFeatureManagementDomainModule : AbpModule
options.MapCodeNamespace("AbpFeatureManagement", typeof(AbpFeatureManagementResource));
});
}
private readonly CancellationTokenSource _cancellationTokenSource = new();
public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
{
InitializeDynamicFeatures(context);
return Task.CompletedTask;
}
public override Task OnApplicationShutdownAsync(ApplicationShutdownContext context)
{
_cancellationTokenSource.Cancel();
return Task.CompletedTask;
}
private void InitializeDynamicFeatures(ApplicationInitializationContext context)
{
var options = context
.ServiceProvider
.GetRequiredService<IOptions<FeatureManagementOptions>>()
.Value;
if (!options.SaveStaticFeaturesToDatabase && !options.IsDynamicFeatureStoreEnabled)
{
return;
}
var rootServiceProvider = context.ServiceProvider.GetRequiredService<IRootServiceProvider>();
Task.Run(async () =>
{
using var scope = rootServiceProvider.CreateScope();
var applicationLifetime = scope.ServiceProvider.GetService<IHostApplicationLifetime>();
var cancellationTokenProvider = scope.ServiceProvider.GetRequiredService<ICancellationTokenProvider>();
var cancellationToken = applicationLifetime?.ApplicationStopping ?? _cancellationTokenSource.Token;
try
{
using (cancellationTokenProvider.Use(cancellationToken))
{
if (cancellationTokenProvider.Token.IsCancellationRequested)
{
return;
}
await SaveStaticFeaturesToDatabaseAsync(options, scope, cancellationTokenProvider);
if (cancellationTokenProvider.Token.IsCancellationRequested)
{
return;
}
await PreCacheDynamicFeaturesAsync(options, scope);
}
}
// ReSharper disable once EmptyGeneralCatchClause (No need to log since it is logged above)
catch { }
});
}
private static async Task SaveStaticFeaturesToDatabaseAsync(
FeatureManagementOptions options,
IServiceScope scope,
ICancellationTokenProvider cancellationTokenProvider)
{
if (!options.SaveStaticFeaturesToDatabase)
{
return;
}
await Policy
.Handle<Exception>()
.WaitAndRetryAsync(8, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10))
.ExecuteAsync(async _ =>
{
try
{
// ReSharper disable once AccessToDisposedClosure
await scope
.ServiceProvider
.GetRequiredService<IStaticFeatureSaver>()
.SaveAsync();
}
catch (Exception ex)
{
// ReSharper disable once AccessToDisposedClosure
scope.ServiceProvider
.GetService<ILogger<AbpFeatureManagementDomainModule>>()?
.LogException(ex);
throw; // Polly will catch it
}
}, cancellationTokenProvider.Token);
}
private static async Task PreCacheDynamicFeaturesAsync(FeatureManagementOptions options, IServiceScope scope)
{
if (!options.IsDynamicFeatureStoreEnabled)
{
return;
}
try
{
// Pre-cache features, so first request doesn't wait
await scope
.ServiceProvider
.GetRequiredService<IDynamicFeatureDefinitionStore>()
.GetGroupsAsync();
}
catch (Exception ex)
{
// ReSharper disable once AccessToDisposedClosure
scope
.ServiceProvider
.GetService<ILogger<AbpFeatureManagementDomainModule>>()?
.LogException(ex);
throw; // It will be cached in InitializeDynamicFeatures
}
}
}

Loading…
Cancel
Save