From ef604cbd770ae6ec719f9848ede0a1386c2b9d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 14 Apr 2023 23:23:45 +0300 Subject: [PATCH 1/6] complete UOW inside the common lock to prevent conflicts. --- .../StaticPermissionSaver.cs | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs index 594f400a43..0bde8ebb0a 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/StaticPermissionSaver.cs @@ -28,6 +28,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc protected ICancellationTokenProvider CancellationTokenProvider { get; } protected AbpDistributedCacheOptions CacheOptions { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + public StaticPermissionSaver( IStaticPermissionDefinitionStore staticStore, IPermissionGroupDefinitionRecordRepository permissionGroupRepository, @@ -38,8 +40,10 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc IApplicationInfoAccessor applicationInfoAccessor, IAbpDistributedLock distributedLock, IOptions permissionOptions, - ICancellationTokenProvider cancellationTokenProvider) + ICancellationTokenProvider cancellationTokenProvider, + IUnitOfWorkManager unitOfWorkManager) { + UnitOfWorkManager = unitOfWorkManager; StaticStore = staticStore; PermissionGroupRepository = permissionGroupRepository; PermissionRepository = permissionRepository; @@ -52,8 +56,7 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc CacheOptions = cacheOptions.Value; } - [UnitOfWork] - public virtual async Task SaveAsync() + public async Task SaveAsync() { await using var applicationLockHandle = await DistributedLock.TryAcquireAsync( GetApplicationDistributedLockKey() @@ -99,19 +102,40 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc throw new AbpException("Could not acquire distributed lock for saving static permissions!"); } - var hasChangesInGroups = await UpdateChangedPermissionGroupsAsync(permissionGroupRecords); - var hasChangesInPermissions = await UpdateChangedPermissionsAsync(permissionRecords); - - if (hasChangesInGroups ||hasChangesInPermissions) + using (var unitOfWork = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true)) { - await Cache.SetStringAsync( - GetCommonStampCacheKey(), - Guid.NewGuid().ToString(), - new DistributedCacheEntryOptions { - SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? - }, - CancellationTokenProvider.Token - ); + try + { + var hasChangesInGroups = await UpdateChangedPermissionGroupsAsync(permissionGroupRecords); + var hasChangesInPermissions = await UpdateChangedPermissionsAsync(permissionRecords); + + if (hasChangesInGroups || hasChangesInPermissions) + { + await Cache.SetStringAsync( + GetCommonStampCacheKey(), + Guid.NewGuid().ToString(), + new DistributedCacheEntryOptions { + SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? + }, + CancellationTokenProvider.Token + ); + } + } + catch + { + try + { + await unitOfWork.RollbackAsync(); + } + catch + { + /* ignored */ + } + + throw; + } + + await unitOfWork.CompleteAsync(); } } @@ -136,7 +160,8 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc foreach (var permissionGroupRecord in permissionGroupRecords) { - var permissionGroupRecordInDatabase = permissionGroupRecordsInDatabase.GetOrDefault(permissionGroupRecord.Name); + var permissionGroupRecordInDatabase = + permissionGroupRecordsInDatabase.GetOrDefault(permissionGroupRecord.Name); if (permissionGroupRecordInDatabase == null) { /* New group */ @@ -291,4 +316,4 @@ public class StaticPermissionSaver : IStaticPermissionSaver, ITransientDependenc .ToString() .ToMd5(); } -} +} \ No newline at end of file From c61d97f09db800f2292c8f5771ce6cd0cf3ef1be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 14 Apr 2023 23:27:08 +0300 Subject: [PATCH 2/6] PErmission management: complete UOW inside the common lock to prevent conflicts. --- .../FeatureManagement/StaticFeatureSaver.cs | 54 +++++++++++++------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/StaticFeatureSaver.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/StaticFeatureSaver.cs index 5b3e581518..993e3ed32e 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/StaticFeatureSaver.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/StaticFeatureSaver.cs @@ -27,6 +27,8 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency protected AbpFeatureOptions FeatureOptions { get; } protected ICancellationTokenProvider CancellationTokenProvider { get; } protected AbpDistributedCacheOptions CacheOptions { get; } + + protected IUnitOfWorkManager UnitOfWorkManager { get; } public StaticFeatureSaver( IStaticFeatureDefinitionStore staticStore, @@ -38,7 +40,8 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency IApplicationInfoAccessor applicationInfoAccessor, IAbpDistributedLock distributedLock, IOptions featureManagementOptions, - ICancellationTokenProvider cancellationTokenProvider) + ICancellationTokenProvider cancellationTokenProvider, + IUnitOfWorkManager unitOfWorkManager) { StaticStore = staticStore; FeatureGroupRepository = featureGroupRepository; @@ -48,12 +51,12 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency ApplicationInfoAccessor = applicationInfoAccessor; DistributedLock = distributedLock; CancellationTokenProvider = cancellationTokenProvider; + UnitOfWorkManager = unitOfWorkManager; FeatureOptions = featureManagementOptions.Value; CacheOptions = cacheOptions.Value; } - [UnitOfWork] - public virtual async Task SaveAsync() + public async Task SaveAsync() { await using var applicationLockHandle = await DistributedLock.TryAcquireAsync( GetApplicationDistributedLockKey() @@ -99,19 +102,40 @@ public class StaticFeatureSaver : IStaticFeatureSaver, ITransientDependency throw new AbpException("Could not acquire distributed lock for saving static features!"); } - var hasChangesInGroups = await UpdateChangedFeatureGroupsAsync(featureGroupRecords); - var hasChangesInFeatures = await UpdateChangedFeaturesAsync(featureRecords); - - if (hasChangesInGroups ||hasChangesInFeatures) + using (var unitOfWork = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true)) { - await Cache.SetStringAsync( - GetCommonStampCacheKey(), - Guid.NewGuid().ToString(), - new DistributedCacheEntryOptions { - SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? - }, - CancellationTokenProvider.Token - ); + try + { + var hasChangesInGroups = await UpdateChangedFeatureGroupsAsync(featureGroupRecords); + var hasChangesInFeatures = await UpdateChangedFeaturesAsync(featureRecords); + + if (hasChangesInGroups ||hasChangesInFeatures) + { + await Cache.SetStringAsync( + GetCommonStampCacheKey(), + Guid.NewGuid().ToString(), + new DistributedCacheEntryOptions { + SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? + }, + CancellationTokenProvider.Token + ); + } + } + catch + { + try + { + await unitOfWork.RollbackAsync(); + } + catch + { + /* ignored */ + } + + throw; + } + + await unitOfWork.CompleteAsync(); } } From 2ea1276b233cc2e1def28ef795fa9b0984091f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Sat, 15 Apr 2023 00:11:34 +0300 Subject: [PATCH 3/6] Randomize waiting duration on failure --- .../AbpFeatureManagementDomainModule.cs | 9 ++++++++- .../AbpPermissionManagementDomainModule.cs | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) 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 291e947c06..42ad413f3f 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 @@ -133,7 +133,14 @@ public class AbpFeatureManagementDomainModule : AbpModule await Policy .Handle() - .WaitAndRetryAsync(8, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10)) + .WaitAndRetryAsync( + 8, + retryAttempt => TimeSpan.FromSeconds( + RandomHelper.GetRandom( + (int)Math.Pow(2, retryAttempt) * 8, + (int)Math.Pow(2, retryAttempt) * 12) + ) + ) .ExecuteAsync(async _ => { try 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 da96890997..0f40e3c039 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 @@ -118,7 +118,14 @@ public class AbpPermissionManagementDomainModule : AbpModule await Policy .Handle() - .WaitAndRetryAsync(8, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10)) + .WaitAndRetryAsync( + 8, + retryAttempt => TimeSpan.FromSeconds( + RandomHelper.GetRandom( + (int)Math.Pow(2, retryAttempt) * 8, + (int)Math.Pow(2, retryAttempt) * 12) + ) + ) .ExecuteAsync(async _ => { try From 13a5a9e7886f4bcb4170322a9743c77a23a2d8c4 Mon Sep 17 00:00:00 2001 From: minhtaile2712 Date: Thu, 20 Apr 2023 11:50:24 +0700 Subject: [PATCH 4/6] Update Distributed-Event-Bus-Kafka-Integration.md --- docs/en/Distributed-Event-Bus-Kafka-Integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Distributed-Event-Bus-Kafka-Integration.md b/docs/en/Distributed-Event-Bus-Kafka-Integration.md index 57a90c4b83..82e658f48d 100644 --- a/docs/en/Distributed-Event-Bus-Kafka-Integration.md +++ b/docs/en/Distributed-Event-Bus-Kafka-Integration.md @@ -110,7 +110,7 @@ You can use any of the [ClientConfig](https://docs.confluent.io/current/clients/ ### The Options Classes -`AbpRabbitMqOptions` and `AbpRabbitMqEventBusOptions` classes can be used to configure the connection strings and event bus options for the RabbitMQ. +`AbpKafkaOptions` and `AbpKafkaEventBusOptions` classes can be used to configure the connection strings and event bus options for the Kafka. You can configure this options inside the `ConfigureServices` of your [module](Module-Development-Basics.md). From face6ebf04da2cc47ee2753e793461a409508e03 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:39:26 +0300 Subject: [PATCH 5/6] Normalize elementId for navigation menu items --- .../Abp/Ui/Navigation/ApplicationMenuGroup.cs | 15 +++++++++++++-- .../Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs index 469c0ad355..09cc9d15b6 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs @@ -5,6 +5,7 @@ namespace Volo.Abp.UI.Navigation; public class ApplicationMenuGroup { private string _displayName; + private string _elementId; /// /// Default value of a group item. @@ -32,7 +33,12 @@ public class ApplicationMenuGroup /// /// Can be used to render the element with a specific Id for DOM selections. /// - public string ElementId { get; set; } + public string ElementId { + get { return _elementId; } + set { + _elementId = NormalizeElementId(value); + } + } /// /// The Display order of the group. @@ -57,7 +63,12 @@ public class ApplicationMenuGroup private string GetDefaultElementId() { - return "MenuGroup_" + Name; + return "MenuGroup" + Name; + } + + private string NormalizeElementId(string elementId) + { + return elementId?.Replace("_", "").Replace(".", ""); } public override string ToString() diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs index dc1614e3e5..9da6e09d16 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs @@ -8,6 +8,7 @@ namespace Volo.Abp.UI.Navigation; public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers { private string _displayName; + private string _elementId; /// /// Default value of a menu item. @@ -85,7 +86,12 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers /// Can be used to render the element with a specific Id for DOM selections. /// - public string ElementId { get; set; } + public string ElementId { + get { return _elementId; } + set { + _elementId = NormalizeElementId(value); + } + } /// /// Can be used to render the element with extra CSS classes. @@ -149,7 +155,12 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers Date: Thu, 20 Apr 2023 11:47:00 +0300 Subject: [PATCH 6/6] Update ApplicationMenuItem.cs --- .../Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs | 4 ++-- .../Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs index 09cc9d15b6..1f4b4ac871 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuGroup.cs @@ -63,12 +63,12 @@ public class ApplicationMenuGroup private string GetDefaultElementId() { - return "MenuGroup" + Name; + return "MenuGroup_" + Name; } private string NormalizeElementId(string elementId) { - return elementId?.Replace("_", "").Replace(".", ""); + return elementId?.Replace(".", ""); } public override string ToString() diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs index 9da6e09d16..b9503874cc 100644 --- a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs @@ -155,12 +155,12 @@ public class ApplicationMenuItem : IHasMenuItems, IHasSimpleStateCheckers