Browse Source

Use hostApplicationLifetime.ApplicationStopping to cancel the operation for saving permissions

pull/13644/head
Halil İbrahim Kalkan 4 years ago
parent
commit
9c8b5ee79c
  1. 49
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs
  2. 24
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs

49
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Polly; using Polly;
@ -10,6 +11,7 @@ using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain; using Volo.Abp.Domain;
using Volo.Abp.Json; using Volo.Abp.Json;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Threading;
namespace Volo.Abp.PermissionManagement; namespace Volo.Abp.PermissionManagement;
@ -37,36 +39,41 @@ public class AbpPermissionManagementDomainModule : AbpModule
private static void SaveStaticPermissionsToDatabase(ApplicationInitializationContext context) private static void SaveStaticPermissionsToDatabase(ApplicationInitializationContext context)
{ {
var rootServiceProvider = context.ServiceProvider.GetRequiredService<IRootServiceProvider>(); var rootServiceProvider = context.ServiceProvider.GetRequiredService<IRootServiceProvider>();
var hostApplicationLifetime = context.ServiceProvider.GetRequiredService<IHostApplicationLifetime>();
Task.Run(async () => Task.Run(async () =>
{ {
using var scope = rootServiceProvider.CreateScope(); using var scope = rootServiceProvider.CreateScope();
var cancellationTokenProvider = scope.ServiceProvider.GetRequiredService<ICancellationTokenProvider>();
try try
{ {
await Policy using (cancellationTokenProvider.Use(hostApplicationLifetime.ApplicationStopping))
.Handle<Exception>() {
.WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10)) await Policy
.ExecuteAsync(async () => .Handle<Exception>()
{ .WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10))
try .ExecuteAsync(async _ =>
{ {
// ReSharper disable once AccessToDisposedClosure try
await scope {
.ServiceProvider // ReSharper disable once AccessToDisposedClosure
.GetRequiredService<IStaticPermissionSaver>() await scope
.SaveAsync(); .ServiceProvider
} .GetRequiredService<IStaticPermissionSaver>()
catch (Exception ex) .SaveAsync();
{ }
// ReSharper disable once AccessToDisposedClosure catch (Exception ex)
scope.ServiceProvider {
.GetService<ILogger<AbpPermissionManagementDomainModule>>()? // ReSharper disable once AccessToDisposedClosure
.LogException(ex); scope.ServiceProvider
.GetService<ILogger<AbpPermissionManagementDomainModule>>()?
.LogException(ex);
throw; // Polly will catch it throw; // Polly will catch it
} }
}); }, cancellationTokenProvider.Token);
}
} }
// ReSharper disable once EmptyGeneralCatchClause (No need to log since it is logged above) // ReSharper disable once EmptyGeneralCatchClause (No need to log since it is logged above)
catch { } catch { }

24
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs

@ -10,6 +10,7 @@ using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking; using Volo.Abp.DistributedLocking;
using Volo.Abp.Threading;
using Volo.Abp.Uow; using Volo.Abp.Uow;
namespace Volo.Abp.PermissionManagement; namespace Volo.Abp.PermissionManagement;
@ -24,6 +25,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
protected IApplicationNameAccessor ApplicationNameAccessor { get; } protected IApplicationNameAccessor ApplicationNameAccessor { get; }
protected IAbpDistributedLock DistributedLock { get; } protected IAbpDistributedLock DistributedLock { get; }
protected PermissionManagementOptions PermissionManagementOptions { get; } protected PermissionManagementOptions PermissionManagementOptions { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
protected AbpDistributedCacheOptions CacheOptions { get; } protected AbpDistributedCacheOptions CacheOptions { get; }
public StaticPermissionSaver( public StaticPermissionSaver(
@ -35,7 +37,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
IOptions<AbpDistributedCacheOptions> cacheOptions, IOptions<AbpDistributedCacheOptions> cacheOptions,
IApplicationNameAccessor applicationNameAccessor, IApplicationNameAccessor applicationNameAccessor,
IAbpDistributedLock distributedLock, IAbpDistributedLock distributedLock,
IOptions<PermissionManagementOptions> permissionManagementOptions) IOptions<PermissionManagementOptions> permissionManagementOptions,
ICancellationTokenProvider cancellationTokenProvider)
{ {
StaticStore = staticStore; StaticStore = staticStore;
PermissionGroupRepository = permissionGroupRepository; PermissionGroupRepository = permissionGroupRepository;
@ -44,6 +47,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
Cache = cache; Cache = cache;
ApplicationNameAccessor = applicationNameAccessor; ApplicationNameAccessor = applicationNameAccessor;
DistributedLock = distributedLock; DistributedLock = distributedLock;
CancellationTokenProvider = cancellationTokenProvider;
PermissionManagementOptions = permissionManagementOptions.Value; PermissionManagementOptions = permissionManagementOptions.Value;
CacheOptions = cacheOptions.Value; CacheOptions = cacheOptions.Value;
} }
@ -53,7 +57,10 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
{ {
/* TODO: We may double check and lock for optimization /* TODO: We may double check and lock for optimization
*/ */
await using var applicationLockHandle = await DistributedLock.TryAcquireAsync(GetApplicationDistributedLockKey()); await using var applicationLockHandle = await DistributedLock.TryAcquireAsync(
GetApplicationDistributedLockKey()
);
if (applicationLockHandle == null) if (applicationLockHandle == null)
{ {
/* Another application instance is already doing it */ /* Another application instance is already doing it */
@ -66,7 +73,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
*/ */
var cacheKey = GetApplicationHashCacheKey(); var cacheKey = GetApplicationHashCacheKey();
var cachedHash = await Cache.GetStringAsync(cacheKey); var cachedHash = await Cache.GetStringAsync(cacheKey, CancellationTokenProvider.Token);
var (permissionGroupRecords, permissionRecords) = await PermissionSerializer.SerializeAsync( var (permissionGroupRecords, permissionRecords) = await PermissionSerializer.SerializeAsync(
await StaticStore.GetGroupsAsync() await StaticStore.GetGroupsAsync()
@ -84,8 +91,9 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
return; return;
} }
await using (var commonLockHandle = await DistributedLock await using (var commonLockHandle = await DistributedLock.TryAcquireAsync(
.TryAcquireAsync(GetCommonDistributedLockKey(), TimeSpan.FromMinutes(5))) GetCommonDistributedLockKey(),
TimeSpan.FromMinutes(5)))
{ {
if (commonLockHandle == null) if (commonLockHandle == null)
{ {
@ -103,7 +111,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
Guid.NewGuid().ToString(), Guid.NewGuid().ToString(),
new DistributedCacheEntryOptions { new DistributedCacheEntryOptions {
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
} },
CancellationTokenProvider.Token
); );
} }
} }
@ -113,7 +122,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
currentHash, currentHash,
new DistributedCacheEntryOptions { new DistributedCacheEntryOptions {
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
} },
CancellationTokenProvider.Token
); );
} }

Loading…
Cancel
Save