Hi @ismcagdas,
I just tried with 6.6.1 and it is not working. If I deactivate usePerRequestRedisCache option like below, everything works again :
Configuration.Caching.UseRedis(options =>
{
options.ConnectionString = _appConfiguration["Abp:RedisCache:ConnectionString"];
options.DatabaseId = _appConfiguration.GetValue<int>("Abp:RedisCache:DatabaseId");
}, usePerRequestRedisCache : false);
If I connect to host, I have following error :
ERROR 2021-12-02 16:18:33,653 [28 ] Mvc.ExceptionHandling.AbpExceptionFilter - Unable to cast object of type 'Abp.Authorization.Users.UserPermissionCacheItem' to type 'Abp.Authorization.Roles.RolePermissionCacheItem'.
System.InvalidCastException: Unable to cast object of type 'Abp.Authorization.Users.UserPermissionCacheItem' to type 'Abp.Authorization.Roles.RolePermissionCacheItem'.
at Abp.Runtime.Caching.TypedCacheWrapper`2.GetAsync(TKey key, Func`2 factory)
at Abp.Authorization.Roles.AbpRoleManager`2.GetRolePermissionCacheItemAsync(Int32 roleId)
at Abp.Authorization.Roles.AbpRoleManager`2.IsGrantedAsync(Int32 roleId, Permission permission)
at Abp.Authorization.Users.AbpUserManager`2.IsGrantedAsync(Int64 userId, Permission permission)
at Abp.Authorization.Users.AbpUserManager`2.IsGrantedAsync(Int64 userId, String permissionName)
at Abp.Authorization.PermissionChecker`2.IsGrantedAsync(Int64 userId, String permissionName)
at Abp.Authorization.PermissionChecker`2.IsGrantedAsync(String permissionName)
at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetUserAuthConfig()
at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetAll()
at Abp.AspNetCore.Mvc.Controllers.AbpUserConfigurationController.GetAll()
at lambda_method1396(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
If I connect to a tenant, I have following error :
ERROR 2021-12-02 16:18:54,004 [33 ] Mvc.ExceptionHandling.AbpExceptionFilter - Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'.
System.InvalidCastException: Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'.
at Abp.Runtime.Caching.TypedCacheWrapper`2.Get(TKey key, Func`2 factory)
at Abp.Runtime.Caching.TypedCacheExtensions.Get[TKey,TValue](ITypedCache`2 cache, TKey key, Func`1 factory)
at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionaryFromCache(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionary(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageManager.GetLanguages(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageManager.GetActiveLanguages(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageProvider.GetActiveLanguages()
at Abp.Localization.LanguageManager.GetActiveLanguages()
at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetUserLocalizationConfig()
at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetAll()
at Abp.AspNetCore.Mvc.Controllers.AbpUserConfigurationController.GetAll()
at lambda_method1396(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
Hi @ismcagdas,
I've updated the project to Abp 6.6 to test redis usePerRequestRedisCache option. When I activate redis with this option, I'm getting an Internal Server Error :
ERROR 2021-11-30 18:23:14,135 [36 ] Mvc.ExceptionHandling.AbpExceptionFilter - Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'.
System.InvalidCastException: Unable to cast object of type 'Abp.MultiTenancy.TenantCacheItem' to type 'System.Collections.Generic.Dictionary`2[System.String,Abp.Localization.ApplicationLanguage]'.
at Abp.Runtime.Caching.TypedCacheWrapper`2.Get(TKey key, Func`2 factory)
at Abp.Runtime.Caching.TypedCacheExtensions.Get[TKey,TValue](ITypedCache`2 cache, TKey key, Func`1 factory)
at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionaryFromCache(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageManager.GetLanguageDictionary(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageManager.GetLanguages(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageManager.GetActiveLanguages(Nullable`1 tenantId)
at Abp.Localization.ApplicationLanguageProvider.GetActiveLanguages()
at Abp.Localization.LanguageManager.GetActiveLanguages()
at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetUserLocalizationConfig()
at Abp.Web.Configuration.AbpUserConfigurationBuilder.GetAll()
at Abp.AspNetCore.Mvc.Controllers.AbpUserConfigurationController.GetAll()
at lambda_method1396(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
I've followed abp documentation to activate this option : import NuGet package and add depends on. Then, I use it like that :
Configuration.Caching.UseRedis(options =>
{
options.ConnectionString = _appConfiguration["Abp:RedisCache:ConnectionString"];
options.DatabaseId = _appConfiguration.GetValue<int>("Abp:RedisCache:DatabaseId");
}, usePerRequestRedisCache: true);
if I deactivate option usePerRequestRedisCache, the app works again.
Could you please check it ?
Hi @ismcagdas,
Tks for your quick answer. I will do it.
ABP 6.4 Angular .NET 5
Hi,
I'm using zero for a while now and the journey for getting a performant app is quite hard :) As the trafic grows, I had to switch SignalR from self hosted to dedicated service. I also had to configure app scaling according to trafic load. I'm running on Azure and my app is currently scaling out to 2 or 3 instances.
Multi-instances means also cache issues... then I switch MemoryCache to RedisCache. Every thing works as expected on production but the app is, at least, two times slower when it comes to get information from cache. GetAll method access as increased a lot...
I've followed all previous post about Redis performance and AbpPerRequestRedisCache.
Should I use AbpPerRequestRedisCache for the entire project ? What happens if a tenant setting is changed in one instance ? The other instances will not be aware of it and will use invalid data no ?
I've tried to test it by following the docs : https://aspnetboilerplate.com/Pages/Documents/PerRequestRedisCache I was able to download nuget package and add [DependsOn(typeof(AbpAspNetCorePerRequestRedisCacheModule))] but I don't found the way to activate option usePerRequestRedisCache to true
Configuration.Caching.UseRedis(usePerRequestRedisCache: true);
How can I activate it ?
Sorry for all that questions but app performance is really sensitive for all users
Hi @ismcagdas,
Tks for your answer, I will implement redis then.
I'm seeing more and more questions about multiple instance management for aspnetboilerplate. It is a very common use case to scale out an application according to workload. I'm currently facing these issue with Azure App Service.
When an application is scalled, you can have lots of issues, like :
It will be nice if you guys could create some docs or guidelines about multiple instance management with zero and aspnetboilerplate
Hi @musa.demir,
Thanks for your answer. I'm having issue with backgroundworkers on multiple instances, see https://github.com/aspnetzero/aspnet-zero-core/issues/4103. Thefore, I just wanted to confirm if something similar could happen with webhooks. In fact, background job should not be an issue on multiple instance context.
Hi support team,
I've implemented webhooks system on my dev machine. Everything works as exptected.
My question is how does this behave with multiple intance ? Don't we have a risk that a webhook is executed twice or more if multiple instance are active ?
I'm currently having some issues when switching to 2 or more instances like cache management and related features. This is also leading to performance issues...
I know that some related issues are existing in your github repos (aspboilerplate and zero), thus, I would like your advice before planning a deployment on production.
Tks
Hi @ismcagdas,
Any news about my previous question for CacheManager ?
Hi @ismcagdas,
I'm using Abp 6.4. I can add a log as you requested and come back to you after.
While analysing this issue on my code, I found that CreateJwtClaims method uses CacheManager... And I just figured out that I'm having issues with CacheManager when my Azure AppService is running on multiple instance. For example, when running with 2 instances, I'm not able to switch user to different tenant accounts (like this https://support.aspnetzero.com/QA/Questions/9502/Switching-tenant-fails-in-mutiple-docker-container-instances-setup)
Therefore, I'm wondering if all these issue are coming from cache management ? (Should I use Redis ?) What do you think ?