diff --git a/Directory.Packages.props b/Directory.Packages.props index 820f8a2b33..feb34a4971 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,7 +7,6 @@ - diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiCurrentApplicationConfigurationCacheResetService.cs b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiCurrentApplicationConfigurationCacheResetService.cs index ad2f6ba983..26e51dbd38 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiCurrentApplicationConfigurationCacheResetService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiCurrentApplicationConfigurationCacheResetService.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Volo.Abp.AspNetCore.Components.Web.Configuration; using Volo.Abp.DependencyInjection; @@ -16,7 +17,7 @@ public class MauiCurrentApplicationConfigurationCacheResetService : _mauiBlazorCachedApplicationConfigurationClient = mauiBlazorCachedApplicationConfigurationClient; } - public async Task ResetAsync() + public async Task ResetAsync(Guid? userId = null) { await _mauiBlazorCachedApplicationConfigurationClient.InitializeAsync(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs b/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs index 02de9d8bf7..144d975cb5 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Volo.Abp.AspNetCore.Components.Web.Configuration; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.DependencyInjection; @@ -19,10 +20,8 @@ public class BlazorServerCurrentApplicationConfigurationCacheResetService : _localEventBus = localEventBus; } - public async Task ResetAsync() + public async Task ResetAsync(Guid? userId = null) { - await _localEventBus.PublishAsync( - new CurrentApplicationConfigurationCacheResetEventData() - ); + await _localEventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData(userId)); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs index c3e33a9e41..2d44399f9d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs @@ -1,8 +1,9 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; namespace Volo.Abp.AspNetCore.Components.Web.Configuration; public interface ICurrentApplicationConfigurationCacheResetService { - Task ResetAsync(); + Task ResetAsync(Guid? userId = null); } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs index bb91d70775..1cfaee3315 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -5,7 +6,7 @@ namespace Volo.Abp.AspNetCore.Components.Web.Configuration; public class NullCurrentApplicationConfigurationCacheResetService : ICurrentApplicationConfigurationCacheResetService, ISingletonDependency { - public Task ResetAsync() + public Task ResetAsync(Guid? userId = null) { return Task.CompletedTask; } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Configuration/BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Configuration/BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService.cs index 40ac508030..359678daf4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Configuration/BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Configuration/BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Volo.Abp.AspNetCore.Components.Web.Configuration; using Volo.Abp.DependencyInjection; @@ -16,7 +17,7 @@ public class BlazorWebAssemblyCurrentApplicationConfigurationCacheResetService : _webAssemblyCachedApplicationConfigurationClient = webAssemblyCachedApplicationConfigurationClient; } - public async Task ResetAsync() + public async Task ResetAsync(Guid? userId = null) { await _webAssemblyCachedApplicationConfigurationClient.InitializeAsync(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs index cc1180fd20..ea0d778fad 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs @@ -1,13 +1,26 @@ -using System.Globalization; -using Volo.Abp.Users; +using System; +using System.Globalization; +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.Mvc.Client; -public static class MvcCachedApplicationConfigurationClientHelper +public class MvcCachedApplicationConfigurationClientHelper : ITransientDependency { - public static string CreateCacheKey(ICurrentUser currentUser) + protected IDistributedCache ApplicationVersionCache { get; } + + public MvcCachedApplicationConfigurationClientHelper(IDistributedCache applicationVersionCache) + { + ApplicationVersionCache = applicationVersionCache; + } + + public virtual async Task CreateCacheKeyAsync(Guid? userId) { - var userKey = currentUser.Id?.ToString("N") ?? "Anonymous"; - return $"ApplicationConfiguration_{userKey}_{CultureInfo.CurrentUICulture.Name}"; + var appVersion = await ApplicationVersionCache.GetOrAddAsync(MvcCachedApplicationVersionCacheItem.CacheKey, + () => Task.FromResult(new MvcCachedApplicationVersionCacheItem(Guid.NewGuid().ToString("N")))) ?? + new MvcCachedApplicationVersionCacheItem(Guid.NewGuid().ToString("N")); + var userKey = userId?.ToString("N") ?? "Anonymous"; + return $"ApplicationConfiguration_{appVersion.Version}_{userKey}_{CultureInfo.CurrentUICulture.Name}"; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationVersionCacheItem.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationVersionCacheItem.cs new file mode 100644 index 0000000000..1cd9990a44 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationVersionCacheItem.cs @@ -0,0 +1,13 @@ +namespace Volo.Abp.AspNetCore.Mvc.Client; + +public class MvcCachedApplicationVersionCacheItem +{ + public const string CacheKey = "Mvc_Application_Version"; + + public string Version { get; set; } + + public MvcCachedApplicationVersionCacheItem(string version) + { + Version = version; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs index 8d787bec65..ba42b55d18 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs @@ -20,6 +20,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP protected IHttpClientFactory HttpClientFactory { get; } protected IRemoteServiceHttpClientAuthenticator HttpClientAuthenticator { get; } protected IDistributedCache ApplicationConfigurationDtoCache { get; } + protected MvcCachedApplicationConfigurationClientHelper CacheHelper { get; } protected ICurrentUser CurrentUser { get; } public RemoteDynamicClaimsPrincipalContributorCache( @@ -28,7 +29,8 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP IOptions abpClaimsPrincipalFactoryOptions, IRemoteServiceHttpClientAuthenticator httpClientAuthenticator, IDistributedCache applicationConfigurationDtoCache, - ICurrentUser currentUser) + ICurrentUser currentUser, + MvcCachedApplicationConfigurationClientHelper cacheHelper) : base(abpClaimsPrincipalFactoryOptions) { Cache = cache; @@ -36,6 +38,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP HttpClientAuthenticator = httpClientAuthenticator; ApplicationConfigurationDtoCache = applicationConfigurationDtoCache; CurrentUser = currentUser; + CacheHelper = cacheHelper; } protected async override Task GetCacheAsync(Guid userId, Guid? tenantId = null) @@ -56,7 +59,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP catch (Exception e) { Logger.LogWarning(e, $"Failed to refresh remote claims for user: {userId}"); - await ApplicationConfigurationDtoCache.RemoveAsync(MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser)); + await ApplicationConfigurationDtoCache.RemoveAsync(await CacheHelper.CreateCacheKeyAsync(CurrentUser.Id)); throw; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs index 0bff9d09b1..e3d3c12370 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClient.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.AspNetCore.Http; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Distributed; @@ -13,14 +14,18 @@ namespace Volo.Abp.AspNetCore.Mvc.Client; public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency { + private const string ApplicationConfigurationDtoCacheKey = "ApplicationConfigurationDto_CacheKey"; + protected IHttpContextAccessor HttpContextAccessor { get; } protected AbpApplicationConfigurationClientProxy ApplicationConfigurationAppService { get; } protected AbpApplicationLocalizationClientProxy ApplicationLocalizationClientProxy { get; } protected ICurrentUser CurrentUser { get; } + protected MvcCachedApplicationConfigurationClientHelper CacheHelper { get; } protected IDistributedCache Cache { get; } protected AbpAspNetCoreMvcClientCacheOptions Options { get; } public MvcCachedApplicationConfigurationClient( + MvcCachedApplicationConfigurationClientHelper cacheHelper, IDistributedCache cache, AbpApplicationConfigurationClientProxy applicationConfigurationAppService, ICurrentUser currentUser, @@ -33,13 +38,27 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu HttpContextAccessor = httpContextAccessor; ApplicationLocalizationClientProxy = applicationLocalizationClientProxy; Options = options.Value; + CacheHelper = cacheHelper; Cache = cache; } - public async Task GetAsync() + public virtual async Task GetAsync() { - var cacheKey = CreateCacheKey(); + string? cacheKey = null; var httpContext = HttpContextAccessor?.HttpContext; + if (httpContext != null && httpContext.Items[ApplicationConfigurationDtoCacheKey] is string key) + { + cacheKey = key; + } + + if (cacheKey.IsNullOrWhiteSpace()) + { + cacheKey = await CreateCacheKeyAsync(); + if (httpContext != null) + { + httpContext.Items[ApplicationConfigurationDtoCacheKey] = cacheKey; + } + } if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration) { @@ -86,8 +105,21 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu public ApplicationConfigurationDto Get() { - var cacheKey = CreateCacheKey(); + string? cacheKey = null; var httpContext = HttpContextAccessor?.HttpContext; + if (httpContext != null && httpContext.Items[ApplicationConfigurationDtoCacheKey] is string key) + { + cacheKey = key; + } + + if (cacheKey.IsNullOrWhiteSpace()) + { + cacheKey = AsyncHelper.RunSync(CreateCacheKeyAsync); + if (httpContext != null) + { + httpContext.Items[ApplicationConfigurationDtoCacheKey] = cacheKey; + } + } if (httpContext != null && httpContext.Items[cacheKey] is ApplicationConfigurationDto configuration) { @@ -97,8 +129,8 @@ public class MvcCachedApplicationConfigurationClient : ICachedApplicationConfigu return AsyncHelper.RunSync(GetAsync); } - protected virtual string CreateCacheKey() + protected virtual async Task CreateCacheKeyAsync() { - return MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser); + return await CacheHelper.CreateCacheKeyAsync(CurrentUser.Id); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs index 8bd3971779..c32b63249c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCurrentApplicationConfigurationCacheResetEventHandler.cs @@ -3,7 +3,6 @@ using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus; -using Volo.Abp.Users; namespace Volo.Abp.AspNetCore.Mvc.Client; @@ -11,23 +10,29 @@ public class MvcCurrentApplicationConfigurationCacheResetEventHandler : ILocalEventHandler, ITransientDependency { - protected ICurrentUser CurrentUser { get; } protected IDistributedCache Cache { get; } + protected IDistributedCache ApplicationVersionCache { get; } + protected MvcCachedApplicationConfigurationClientHelper CacheHelper { get; } - public MvcCurrentApplicationConfigurationCacheResetEventHandler(ICurrentUser currentUser, - IDistributedCache cache) + public MvcCurrentApplicationConfigurationCacheResetEventHandler( + IDistributedCache cache, + IDistributedCache applicationVersionCache, + MvcCachedApplicationConfigurationClientHelper cacheHelper) { - CurrentUser = currentUser; Cache = cache; + ApplicationVersionCache = applicationVersionCache; + CacheHelper = cacheHelper; } public virtual async Task HandleEventAsync(CurrentApplicationConfigurationCacheResetEventData eventData) { - await Cache.RemoveAsync(CreateCacheKey()); - } - - protected virtual string CreateCacheKey() - { - return MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser); + if (eventData.UserId.HasValue) + { + await Cache.RemoveAsync(await CacheHelper.CreateCacheKeyAsync(eventData.UserId)); + } + else + { + await ApplicationVersionCache.RemoveAsync(MvcCachedApplicationVersionCacheItem.CacheKey); + } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs index a50cb7b136..fccc295429 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentApplicationConfigurationCacheResetEventData.cs @@ -1,9 +1,21 @@ -namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using System; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; /// /// This event is used to invalidate current user's cached configuration. /// public class CurrentApplicationConfigurationCacheResetEventData { + public Guid? UserId { get; set; } + + public CurrentApplicationConfigurationCacheResetEventData() + { + + } + public CurrentApplicationConfigurationCacheResetEventData(Guid? userId) + { + UserId = userId; + } } diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj index 83f8f0076b..773c954051 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo.Abp.DistributedLocking.Abstractions.csproj @@ -18,7 +18,6 @@ - diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs index 15956b159e..d8d8eb9d09 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLock.cs @@ -1,19 +1,14 @@ using System; -using System.Runtime.CompilerServices; +using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; -using AsyncKeyedLock; using Volo.Abp.DependencyInjection; namespace Volo.Abp.DistributedLocking; public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency { - private readonly AsyncKeyedLocker _localSyncObjects = new(o => - { - o.PoolSize = 20; - o.PoolInitialFill = 1; - }); + private readonly ConcurrentDictionary _localSyncObjects = new(); protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; } public LocalAbpDistributedLock(IDistributedLockKeyNormalizer distributedLockKeyNormalizer) @@ -21,7 +16,6 @@ public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency DistributedLockKeyNormalizer = distributedLockKeyNormalizer; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public async Task TryAcquireAsync( string name, TimeSpan timeout = default, @@ -30,11 +24,8 @@ public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency Check.NotNullOrWhiteSpace(name, nameof(name)); var key = DistributedLockKeyNormalizer.NormalizeKey(name); - var timeoutReleaser = await _localSyncObjects.LockOrNullAsync(key, timeout, cancellationToken); - if (timeoutReleaser is not null) - { - return new LocalAbpDistributedLockHandle(timeoutReleaser); - } - return null; + var semaphore = _localSyncObjects.GetOrAdd(key, _ => new SemaphoreSlim(1, 1)); + var acquired = await semaphore.WaitAsync(timeout, cancellationToken); + return acquired ? new LocalAbpDistributedLockHandle(semaphore) : null; } } diff --git a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLockHandle.cs b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLockHandle.cs index d08451657e..5ffe95af5e 100644 --- a/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLockHandle.cs +++ b/framework/src/Volo.Abp.DistributedLocking.Abstractions/Volo/Abp/DistributedLocking/LocalAbpDistributedLockHandle.cs @@ -1,20 +1,21 @@ -using System; +using System.Threading; using System.Threading.Tasks; -namespace Volo.Abp.DistributedLocking; - -public class LocalAbpDistributedLockHandle : IAbpDistributedLockHandle +namespace Volo.Abp.DistributedLocking { - private readonly IDisposable _disposable; - - public LocalAbpDistributedLockHandle(IDisposable disposable) + public class LocalAbpDistributedLockHandle : IAbpDistributedLockHandle { - _disposable = disposable; - } + private readonly SemaphoreSlim _semaphore; - public ValueTask DisposeAsync() - { - _disposable.Dispose(); - return default; + public LocalAbpDistributedLockHandle(SemaphoreSlim semaphore) + { + _semaphore = semaphore; + } + + public ValueTask DisposeAsync() + { + _semaphore.Release(); + return default; + } } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs index 95d892692e..1c465817f2 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs @@ -25,7 +25,6 @@ namespace Volo.Abp.FeatureManagement; public class AbpFeatureManagementDomainModule : AbpModule { private readonly CancellationTokenSource _cancellationTokenSource = new(); - private Task _initializeDynamicFeaturesTask; public override void ConfigureServices(ServiceConfigurationContext context) { @@ -65,7 +64,6 @@ public class AbpFeatureManagementDomainModule : AbpModule var rootServiceProvider = context.ServiceProvider.GetRequiredService(); var initializer = rootServiceProvider.GetRequiredService(); await initializer.InitializeAsync(true, _cancellationTokenSource.Token); - _initializeDynamicFeaturesTask = initializer.GetInitializationTask(); } public override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) @@ -73,9 +71,4 @@ public class AbpFeatureManagementDomainModule : AbpModule _cancellationTokenSource.Cancel(); return Task.CompletedTask; } - - public Task GetInitializeDynamicFeaturesTask() - { - return _initializeDynamicFeaturesTask ?? Task.CompletedTask; - } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureDynamicInitializer.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureDynamicInitializer.cs index 9f6820274c..32ed4cb646 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureDynamicInitializer.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/FeatureDynamicInitializer.cs @@ -16,8 +16,6 @@ namespace Volo.Abp.FeatureManagement; public class FeatureDynamicInitializer : ITransientDependency { - private Task _initializeDynamicFeaturesTask; - public ILogger Logger { get; set; } protected IServiceProvider ServiceProvider { get; } @@ -56,7 +54,7 @@ public class FeatureDynamicInitializer : ITransientDependency if (runInBackground) { - _initializeDynamicFeaturesTask = Task.Run(async () => + Task.Run(async () => { if (cancellationToken == default && ApplicationLifetime?.ApplicationStopping != null) { @@ -67,13 +65,7 @@ public class FeatureDynamicInitializer : ITransientDependency return Task.CompletedTask; } - _initializeDynamicFeaturesTask = ExecuteInitializationAsync(options, cancellationToken); - return _initializeDynamicFeaturesTask; - } - - public virtual Task GetInitializationTask() - { - return _initializeDynamicFeaturesTask ?? Task.CompletedTask; + return ExecuteInitializationAsync(options, cancellationToken); } protected virtual async Task ExecuteInitializationAsync(FeatureManagementOptions options, CancellationToken cancellationToken) diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs index c370e5f558..71254e009f 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs @@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; @@ -53,15 +54,8 @@ public class AbpFeatureManagementEntityFrameworkCoreTestModule : AbpModule public override void OnApplicationInitialization(ApplicationInitializationContext context) { - var task = context.ServiceProvider.GetRequiredService().GetInitializeDynamicFeaturesTask(); - if (!task.IsCompleted) - { - AsyncHelper.RunSync(() => Awaited(task)); - } - } - - private async static Task Awaited(Task task) - { - await task; + var rootServiceProvider = context.ServiceProvider.GetRequiredService(); + var initializer = rootServiceProvider.GetRequiredService(); + AsyncHelper.RunSync(() => initializer.InitializeAsync(false)); } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs index 2a618b9d4b..b3c917177b 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs @@ -6,6 +6,7 @@ using Blazorise; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Components.Web.Configuration; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.Localization; using Volo.Abp.PermissionManagement.Localization; @@ -153,7 +154,13 @@ public partial class PermissionManagementModal await PermissionAppService.UpdateAsync(_providerName, _providerKey, updateDto); - await CurrentApplicationConfigurationCacheResetService.ResetAsync(); + Guid? userId = null; + if (_providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(_providerKey, out var parsedUserId)) + { + userId = parsedUserId; + } + + await CurrentApplicationConfigurationCacheResetService.ResetAsync(userId); await InvokeAsync(_modal.Hide); await Notify.Success(L["SavedSuccessfully"]); diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs index e3825ff397..9014b04ac2 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/AbpPermissionManagementDomainModule.cs @@ -26,7 +26,6 @@ namespace Volo.Abp.PermissionManagement; public class AbpPermissionManagementDomainModule : AbpModule { private readonly CancellationTokenSource _cancellationTokenSource = new(); - private Task _initializeDynamicPermissionsTask; public override void ConfigureServices(ServiceConfigurationContext context) { @@ -50,7 +49,6 @@ public class AbpPermissionManagementDomainModule : AbpModule var rootServiceProvider = context.ServiceProvider.GetRequiredService(); var initializer = rootServiceProvider.GetRequiredService(); await initializer.InitializeAsync(true, _cancellationTokenSource.Token); - _initializeDynamicPermissionsTask = initializer.GetInitializationTask(); } public override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) @@ -58,9 +56,4 @@ public class AbpPermissionManagementDomainModule : AbpModule _cancellationTokenSource.Cancel(); return Task.CompletedTask; } - - public Task GetInitializeDynamicPermissionsTask() - { - return _initializeDynamicPermissionsTask ?? Task.CompletedTask; - } } diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDynamicInitializer.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDynamicInitializer.cs index e78885c07f..74bdf1821b 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDynamicInitializer.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDynamicInitializer.cs @@ -16,8 +16,6 @@ namespace Volo.Abp.PermissionManagement; public class PermissionDynamicInitializer : ITransientDependency { - private Task _initializeDynamicPermissionsTask; - public ILogger Logger { get; set; } protected IServiceProvider ServiceProvider { get; } @@ -56,7 +54,7 @@ public class PermissionDynamicInitializer : ITransientDependency if (runInBackground) { - _initializeDynamicPermissionsTask = Task.Run(async () => + Task.Run(async () => { if (cancellationToken == default && ApplicationLifetime?.ApplicationStopping != null) { @@ -67,13 +65,7 @@ public class PermissionDynamicInitializer : ITransientDependency return Task.CompletedTask; } - _initializeDynamicPermissionsTask = ExecuteInitializationAsync(options, cancellationToken); - return _initializeDynamicPermissionsTask; - } - - public virtual Task GetInitializationTask() - { - return _initializeDynamicPermissionsTask ?? Task.CompletedTask; + return ExecuteInitializationAsync(options, cancellationToken); } protected virtual async Task ExecuteInitializationAsync(PermissionManagementOptions options, CancellationToken cancellationToken) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs index 2c9d2dcc1c..6f6d6113e9 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; @@ -6,6 +7,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Authorization.Permissions; using Volo.Abp.EventBus.Local; using Volo.Abp.Localization; using Volo.Abp.PermissionManagement.Web.Utils; @@ -105,9 +107,13 @@ public class PermissionManagementModal : AbpPageModel } ); - await LocalEventBus.PublishAsync( - new CurrentApplicationConfigurationCacheResetEventData() - ); + Guid? userId = null; + if (ProviderName == UserPermissionValueProvider.ProviderName && Guid.TryParse(ProviderKey, out var parsedUserId)) + { + userId = parsedUserId; + } + + await LocalEventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData(userId)); return NoContent(); } @@ -130,7 +136,7 @@ public class PermissionManagementModal : AbpPageModel public bool IsDisabled(string currentProviderName) { var grantedProviders = Permissions.SelectMany(x => x.GrantedProviders); - + return Permissions.All(x => x.IsGranted) && grantedProviders.All(p => p.ProviderName != currentProviderName); } } diff --git a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs index 1e483fe1aa..7db8f8fe7e 100644 --- a/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs +++ b/modules/permission-management/test/Volo.Abp.PermissionManagement.EntityFrameworkCore.Tests/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementEntityFrameworkCoreTestModule.cs @@ -9,6 +9,7 @@ using Volo.Abp.Modularity; using Volo.Abp.Threading; using Volo.Abp.Uow; using Microsoft.Data.Sqlite; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.PermissionManagement.EntityFrameworkCore; @@ -56,18 +57,10 @@ public class AbpPermissionManagementEntityFrameworkCoreTestModule : AbpModule return connection; } - public override void OnApplicationInitialization(ApplicationInitializationContext context) { - var task = context.ServiceProvider.GetRequiredService().GetInitializeDynamicPermissionsTask(); - if (!task.IsCompleted) - { - AsyncHelper.RunSync(() => Awaited(task)); - } - } - - private async static Task Awaited(Task task) - { - await task; + var rootServiceProvider = context.ServiceProvider.GetRequiredService(); + var initializer = rootServiceProvider.GetRequiredService(); + AsyncHelper.RunSync(() => initializer.InitializeAsync(false)); } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs index c3cd35daef..a5d2ba832e 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs @@ -25,7 +25,6 @@ namespace Volo.Abp.SettingManagement; public class AbpSettingManagementDomainModule : AbpModule { private readonly CancellationTokenSource _cancellationTokenSource = new(); - private Task _initializeDynamicSettingsTask; public override void ConfigureServices(ServiceConfigurationContext context) { @@ -58,7 +57,6 @@ public class AbpSettingManagementDomainModule : AbpModule var rootServiceProvider = context.ServiceProvider.GetRequiredService(); var initializer = rootServiceProvider.GetRequiredService(); await initializer.InitializeAsync(true, _cancellationTokenSource.Token); - _initializeDynamicSettingsTask = initializer.GetInitializationTask(); } public override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) @@ -66,9 +64,4 @@ public class AbpSettingManagementDomainModule : AbpModule _cancellationTokenSource.Cancel(); return Task.CompletedTask; } - - public Task GetInitializeDynamicSettingsTask() - { - return _initializeDynamicSettingsTask ?? Task.CompletedTask; - } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDynamicInitializer.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDynamicInitializer.cs index 6f388c8de8..41db669d9b 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDynamicInitializer.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDynamicInitializer.cs @@ -16,8 +16,6 @@ namespace Volo.Abp.SettingManagement; public class SettingDynamicInitializer : ITransientDependency { - private Task _initializeDynamicSettingsTask; - public ILogger Logger { get; set; } protected IServiceProvider ServiceProvider { get; } @@ -56,7 +54,7 @@ public class SettingDynamicInitializer : ITransientDependency if (runInBackground) { - _initializeDynamicSettingsTask = Task.Run(async () => + Task.Run(async () => { if (cancellationToken == default && ApplicationLifetime?.ApplicationStopping != null) { @@ -68,13 +66,7 @@ public class SettingDynamicInitializer : ITransientDependency return Task.CompletedTask; } - _initializeDynamicSettingsTask = ExecuteInitializationAsync(options, cancellationToken); - return _initializeDynamicSettingsTask; - } - - public virtual Task GetInitializationTask() - { - return _initializeDynamicSettingsTask ?? Task.CompletedTask; + return ExecuteInitializationAsync(options, cancellationToken); } protected virtual async Task ExecuteInitializationAsync(SettingManagementOptions options, CancellationToken cancellationToken) diff --git a/text-template-management/src/Volo.Abp.TextTemplateManagement.Domain/Volo/Abp/TextTemplateManagement/StaticTemplateDefinitionChangedEventHandler.cs b/text-template-management/src/Volo.Abp.TextTemplateManagement.Domain/Volo/Abp/TextTemplateManagement/StaticTemplateDefinitionChangedEventHandler.cs new file mode 100644 index 0000000000..86b498ed90 --- /dev/null +++ b/text-template-management/src/Volo.Abp.TextTemplateManagement.Domain/Volo/Abp/TextTemplateManagement/StaticTemplateDefinitionChangedEventHandler.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; +using Volo.Abp.StaticDefinitions; +using Volo.Abp.TextTemplating; +using Volo.Abp.Threading; + +namespace Volo.Abp.TextTemplateManagement; + +public class StaticTemplateDefinitionChangedEventHandler : ILocalEventHandler, ITransientDependency +{ + protected IStaticDefinitionCache> DefinitionCache { get; } + protected TextTemplateDynamicInitializer TextTemplateDynamicInitializer { get; } + protected ICancellationTokenProvider CancellationTokenProvider { get; } + + public StaticTemplateDefinitionChangedEventHandler( + IStaticDefinitionCache> definitionCache, + TextTemplateDynamicInitializer textTemplateDynamicInitializer, + ICancellationTokenProvider cancellationTokenProvider) + { + DefinitionCache = definitionCache; + TextTemplateDynamicInitializer = textTemplateDynamicInitializer; + CancellationTokenProvider = cancellationTokenProvider; + } + + public virtual async Task HandleEventAsync(StaticTemplateDefinitionChangedEvent eventData) + { + await DefinitionCache.ClearAsync(); + await TextTemplateDynamicInitializer.InitializeAsync(false, CancellationTokenProvider.Token); + } +}