Open Closed

Microservice localizations not updating #4667


User avatar
0
steve.burgess created
  • ABP Framework version: v7.0.1
  • UI type: Angularr
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

Hi,

I'm currently using the microservice template.

After upgrading to version 7, updates to the translation files are not appearing in the application.

After updating the translation file and starting the application i can see the new changes correctly being added to the AbpLocalizationTexts table. However, when you start the application and it fetches the localizations from "api/abp/application-localization?cultureName=en&onlyDynamics=false" it returns the old version of the file.

Looking in redis it doesn't look like the cache has been updated with the new values.

Am i missing something? Is there something new i need to be doing in v7?

Thanks,

Steve.


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

    hi

    You can clear the redis and try again.

  • User Avatar
    0
    steve.burgess created

    hi

    You can clear the redis and try again.

    Hi,

    That will fix it yes.

    But should it not be updating the cache when it updates the values in the database?

    I don't really want to be wiping my entire redis cache every time i do a deployment that contains a translation update.

    Cheers,

    Steve.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    But should it not be updating the cache when it updates the values in the database?

    We can update the cache when you change some things via code, but we can't know anything if you change it in the database.

  • User Avatar
    0
    steve.burgess created

    Hi,

    I'm not changing anything in the database.

    The database is being updated with the update localisations via one of the ABP packages.

    All i do is update the en.json file in domain.shared.localizations.service directory and then start the microservices. This then gets automatically added to the AbpLocalizationTexts table in the admin service somehow (not via any of my code).

    Cheers,

    Steve.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I just checked, the module will clear the relevant cache, what are the detailed steps to reproduce the problem?

  • User Avatar
    0
    steve.burgess created

    Hi,

    Ok, sounds like it's something with my setup then. Can you let me know what module the code is in? That way i can pull the source code and debug the issue to see what's happening.

    Cheers,

    Steve.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

  • User Avatar
    0
    steve.burgess created

    hi

    Awesome, thanks.

    Steve.

  • User Avatar
    0
    steve.burgess created

    OK, so tracing this through the system and looking in REDIS the reason why it's not clearing the cache is because it's attempting to remove the wrong key.

    With the redis-cli monitor command you can see that it's running the unlink command and passing it the key c:AbpExternalLocalizationTexts,k:TimeTrackerTimeTrackerService:en

    However, the key in redis is c:AbpExternalLocalizationTexts,k:TimeTracker:TimeTrackerService:en (note the colon between TimeTracker and TimeTrackerService

    It's worth noting that as far as i can tell all the other commands that involve keys being passed to REDIS correctly have a colon between TimeTracker and TimeTrackerService. An example of this is below

    Any ideas?

    Cheers,

    Steve.

  • User Avatar
    0
    steve.burgess created

    OK, so tracing this through the system and looking in REDIS the reason why it's not clearing the cache is because it's attempting to remove the wrong key.

    With the redis-cli monitor command you can see that it's running the unlink command and passing it the key c:AbpExternalLocalizationTexts,k:TimeTrackerTimeTrackerService:en

    However, the key in redis is c:AbpExternalLocalizationTexts,k:TimeTracker:TimeTrackerService:en (note the colon between TimeTracker and TimeTrackerService

    It's worth noting that as far as i can tell all the other commands that involve keys being passed to REDIS correctly have a colon between TimeTracker and TimeTrackerService. An example of this is below

    Any ideas?

    Cheers,

    Steve.

    I think I've found the answer to this.

    If we look in the distributed cache class we can see that the cache key is being constructed via the NormalizeKey method that calls KeyNormalizer.NormalizeKey which is method on an injected IDistributedCacheKeyNormalizer

    https://github.com/abpframework/abp/blob/9d2902b335ca089be6ae07242d4470472de39cf5/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs

    Looking at DistributedCacheKeyNormalizer we can see that when it constructs the key it doesn't include a colon

    https://github.com/abpframework/abp/blob/e3e1779de6df5d26f01cdc8e99ac9cbcb3d24d3c/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCacheKeyNormalizer.cs

    I ignored this initially because the system seemed to be correctly pulling keys from REDIS without issue.

    However, after some more investigation it looks like all the "templates" for various project types in include a colon when setting KeyPrefix on the AbpDistributedCacheOptions. I added a colon to my KeyPrefix and it all appears to be working correctly now.

    Is what i found correct? Or am i missing something?

    Cheers,

    Steve.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Thank you, I will confirm this.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The KeyPrefix of AbpDistributedCacheOptions has been set in all template projects, including the microservice template.

    So also recommend you to do this.

  • User Avatar
    0
    steve.burgess created

    hi

    The KeyPrefix of AbpDistributedCacheOptions has been set in all template projects, including the microservice template.

    So also recommend you to do this.

    Thanks for checking. My question was more around the need for having the colon character : at the end of the prefix. Is the colon required?

    Cheers,

    Steve.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    I don't think a colon character is required.

  • User Avatar
    0
    steve.burgess created

    Sorry, I think I might be making things more complicated than they need to be.

    The issue I’m seeing is that updating the localization files does not result in the redis cache being correctly cleared and this means that the updated localizations do not appear in the frontend. After some investigation I believe this is related to the setting of the KeyPrefix option of AbpDistributedCacheOptions class.

    Steps to reproduce what I’m seeing are below:

    1. Setup a 7.0.1 version of the microservice template with an angular frontend
    2. Open up the ProductServiceApplicationModule.cs file in the ProductService project and add a Keyprefix eg.

    Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "ProductService"; });

    1. Open up home.component.html in the angular project and add this text below the first h2 tag {{ 'ProductService::Menu:ProductService' | abpLocalization }}. This will make it easier to test if the localization is updating.
    2. Start microservices and angular.
    3. Browse to the front page. You don’t need to login, you just need the front page to access the language endpoint so that the localization file is loaded into the cache.
    4. Stop the microservices.
    5. Open up the correct localization file for the language you are using in ProductService.Domain.Shared. Change “Menu:ProductService” to a new value.
    6. Restart the microservices.
    7. Browse to the front page. The value shown for Menu:ProductService shows as the old version and not the updated version (at least for me)
    8. Check administration database (AbpLocalizationTexts) and confirm that your update is actually in the database.
    9. Check the redis cache and confirm that your update has not made it into the cache

    If I don’t set the KeyPrefix the updates work. If I add a colon to the end of the key prefix this also works (I’m not entirely sure why that works)

    Thanks,

    Steve.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I will try to reproduce, thanks

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Microservices will use a cache prefix, It can't clean the cache properly if you use the different prefix in admin and product.

    If I add a colon to the end of the key prefix this also works (I’m not entirely sure why that works)

    I haven't reproduced this.

    In conclusion: You can't use different prefix in several microservice.

  • User Avatar
    0
    steve.burgess created

    hi

    Microservices will use a cache prefix, It can't clean the cache properly if you use the different prefix in admin and product.

    If I add a colon to the end of the key prefix this also works (I’m not entirely sure why that works)

    I haven't reproduced this.

    In conclusion: You can't use different prefix in several microservice.

    OK, thanks for investigating and letting me know.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19