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.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Polly;
@ -10,6 +11,7 @@ using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
using Volo.Abp.Threading;
namespace Volo.Abp.PermissionManagement;
@ -37,36 +39,41 @@ public class AbpPermissionManagementDomainModule : AbpModule
private static void SaveStaticPermissionsToDatabase(ApplicationInitializationContext context)
{
var rootServiceProvider = context.ServiceProvider.GetRequiredService<IRootServiceProvider>();
var hostApplicationLifetime = context.ServiceProvider.GetRequiredService<IHostApplicationLifetime>();
Task.Run(async () =>
{
using var scope = rootServiceProvider.CreateScope();
var cancellationTokenProvider = scope.ServiceProvider.GetRequiredService<ICancellationTokenProvider>();
try
{
await Policy
.Handle<Exception>()
.WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10))
.ExecuteAsync(async () =>
{
try
using (cancellationTokenProvider.Use(hostApplicationLifetime.ApplicationStopping))
{
await Policy
.Handle<Exception>()
.WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10))
.ExecuteAsync(async _ =>
{
// ReSharper disable once AccessToDisposedClosure
await scope
.ServiceProvider
.GetRequiredService<IStaticPermissionSaver>()
.SaveAsync();
}
catch (Exception ex)
{
// ReSharper disable once AccessToDisposedClosure
scope.ServiceProvider
.GetService<ILogger<AbpPermissionManagementDomainModule>>()?
.LogException(ex);
try
{
// ReSharper disable once AccessToDisposedClosure
await scope
.ServiceProvider
.GetRequiredService<IStaticPermissionSaver>()
.SaveAsync();
}
catch (Exception ex)
{
// ReSharper disable once AccessToDisposedClosure
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)
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.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Threading;
using Volo.Abp.Uow;
namespace Volo.Abp.PermissionManagement;
@ -24,6 +25,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
protected IApplicationNameAccessor ApplicationNameAccessor { get; }
protected IAbpDistributedLock DistributedLock { get; }
protected PermissionManagementOptions PermissionManagementOptions { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
protected AbpDistributedCacheOptions CacheOptions { get; }
public StaticPermissionSaver(
@ -35,7 +37,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
IOptions<AbpDistributedCacheOptions> cacheOptions,
IApplicationNameAccessor applicationNameAccessor,
IAbpDistributedLock distributedLock,
IOptions<PermissionManagementOptions> permissionManagementOptions)
IOptions<PermissionManagementOptions> permissionManagementOptions,
ICancellationTokenProvider cancellationTokenProvider)
{
StaticStore = staticStore;
PermissionGroupRepository = permissionGroupRepository;
@ -44,6 +47,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
Cache = cache;
ApplicationNameAccessor = applicationNameAccessor;
DistributedLock = distributedLock;
CancellationTokenProvider = cancellationTokenProvider;
PermissionManagementOptions = permissionManagementOptions.Value;
CacheOptions = cacheOptions.Value;
}
@ -53,7 +57,10 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
{
/* 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)
{
/* Another application instance is already doing it */
@ -66,7 +73,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
*/
var cacheKey = GetApplicationHashCacheKey();
var cachedHash = await Cache.GetStringAsync(cacheKey);
var cachedHash = await Cache.GetStringAsync(cacheKey, CancellationTokenProvider.Token);
var (permissionGroupRecords, permissionRecords) = await PermissionSerializer.SerializeAsync(
await StaticStore.GetGroupsAsync()
@ -84,8 +91,9 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
return;
}
await using (var commonLockHandle = await DistributedLock
.TryAcquireAsync(GetCommonDistributedLockKey(), TimeSpan.FromMinutes(5)))
await using (var commonLockHandle = await DistributedLock.TryAcquireAsync(
GetCommonDistributedLockKey(),
TimeSpan.FromMinutes(5)))
{
if (commonLockHandle == null)
{
@ -103,7 +111,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
Guid.NewGuid().ToString(),
new DistributedCacheEntryOptions {
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
}
},
CancellationTokenProvider.Token
);
}
}
@ -113,7 +122,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc
currentHash,
new DistributedCacheEntryOptions {
SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable?
}
},
CancellationTokenProvider.Token
);
}

Loading…
Cancel
Save