Open Closed

Follow up : Is-there-a-way-to-bypass-Tenant-for-Translations , Performance issue #1987


User avatar
0
thomas.blotiere@abraxas.ch created

Hello,

I have followed the solution that has been suggested as an answer of my initial question here : https://support.abp.io/QA/Questions/1642/Is-there-a-way-to-bypass-Tenant-for-Translations

Technically, this is working fine but what happens is that my code now loads up to 33 ressources and the impact on performance is significant when the user changes of tenant or of language.

I had to disregard this solution because of this performance issue.

Sure I am sure I can remove a few ressources from loading but a few less will not change much of the performance issue.

Can this code be improved ? Or is there a better way to do achieve the same result, that is to access translations independently of the tenant ?

Thank you

Thomas

ABP Framework version: 4.3 UI type: Angular DB provider: EF Core Tiered (MVC) or Identity Server Separated (Angular): yes

`
using Volo.Abp.Caching;
using Volo.Abp.LanguageManagement;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

namespace AbxEps.Fines
{
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IDynamicResourceLocalizer))]
    public class TenantIndependentResourceLocalizer : DynamicResourceLocalizer
    {
        public TenantIndependentResourceLocalizer(
            IServiceScopeFactory serviceScopeFactory,
            IDistributedCache<LanguageTextCacheItem> cache)
            : base(serviceScopeFactory, cache)
        {
        }

        protected override LanguageTextCacheItem CreateCacheItem(LocalizationResource resource, string cultureName)
        {
            var cacheItem = new LanguageTextCacheItem();

            using (var scope = ServiceScopeFactory.CreateScope())
            {
                var currentTenant = scope.ServiceProvider.GetRequiredService<ICurrentTenant>();

                if (currentTenant == null || !currentTenant.IsAvailable)
                    return base.CreateCacheItem(resource, cultureName);

                using (currentTenant.Change(null))
                {
                    var service = scope.ServiceProvider.GetRequiredService<ILanguageTextRepository>();

                    AddToLanguageDictionary("AbpIdentity", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpAccount", cultureName, cacheItem, service);
                    AddToLanguageDictionary("LanguageManagement", cultureName, cacheItem, service);
                    AddToLanguageDictionary("TextTemplateManagement", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpSettingManagement", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpIdentityServer", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpAuditLogging", cultureName, cacheItem, service);
                    AddToLanguageDictionary("CentralTools", cultureName, cacheItem, service);
                    AddToLanguageDictionary("CentralTools:CommonUI", cultureName, cacheItem, service);
                    AddToLanguageDictionary("Fines", cultureName, cacheItem, service);
                    AddToLanguageDictionary("Batches", cultureName, cacheItem, service);
                    AddToLanguageDictionary("ListSpool", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpUi", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpLocalization", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpTiming", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpAuthorization", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpValidation", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpExceptionHandling", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpFeatureManagement", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpFeature", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpPermissionManagement", cultureName, cacheItem, service);
                    AddToLanguageDictionary("Saas", cultureName, cacheItem, service);
                    AddToLanguageDictionary("TextTemplateManagement", cultureName, cacheItem, service);
                    AddToLanguageDictionary("EpsilonThemeManagement", cultureName, cacheItem, service);
                    AddToLanguageDictionary("BlobStoringDatabase", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AuditLog", cultureName, cacheItem, service);
                    AddToLanguageDictionary("Core", cultureName, cacheItem, service);
                    AddToLanguageDictionary("Fines:CommonUI", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpDddApplicationContracts", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpGlobalFeature", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpLdap", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpEmailing", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpUiNavigation", cultureName, cacheItem, service);
                    AddToLanguageDictionary("AbpUiMultiTenancy", cultureName, cacheItem, service);
                }
            }

            return cacheItem;
        }

        private void AddToLanguageDictionary(string resourceName, string cultureName, LanguageTextCacheItem cacheItem, ILanguageTextRepository service)
        {
            var texts = service.GetList(resourceName, cultureName);

            foreach (var text in texts)
            {
                cacheItem.Dictionary[text.Name] = text.Value;
            }
        }
    }
}`

4 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    why do you add so many resource to the Dictionary?

    https://support.abp.io/QA/Questions/1642/Is-there-a-way-to-bypass-Tenant-for-Translations#answer-eea69656-8bb0-af79-e8fb-39fe16c17820

  • User Avatar
    0
    thomas.blotiere@abraxas.ch created

    At first, I only added a few needed ressources.

    But then I found out that many translations were missing.

    It is not always clear to me what resource abp uses to get translations but after adding resources one by one, I ended up adding all ABP resources, just in case as there was always one ressource missing each time I tested.

    Concerning the resources on our side, I can remove 2 at most.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    But then I found out that many translations were missing.

    Can you explain it in details?

    The CreateCacheItem method only get translations dictionary for specific ResourceName and cultureName.

    You shouldn't add other resourceName.

  • User Avatar
    0
    thomas.blotiere@abraxas.ch created

    After digging more with how ressources are loaded and when, I understand my mistake.

    The CreateCacheItem method is already called for every resource ; by adding those dictionaries, I was making many unnecessarily calls.

    For some reason, the exact code https://support.abp.io/QA/Questions/1642/Is-there-a-way-to-bypass-Tenant-for-Translations#answer-eea69656-8bb0-af79-e8fb-39fe16c17820 did not work when I first tried it 2 months ago ( bad copy paste ?) but now it is working.

    Thank you

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11