Hello I have a tiered web app with angular. The problem is on authserver though. I use LeptonX theme and this question is related with MVC LeptonX Theme. On some devices login page box can not fit to the page. Since overflow is hidden on the page, user can not see the login button. When i publish my maui app for release to the apple store, apple store rejected the app. As you know Oauth is used on the maui project. And When the new login page opens on the browser(for ex: on ipad) it doesn't fit on the page. Since user can not scroll, login button is not visible for them. Here some pictures from simulator.
also you can try this on your chrome browser with chrome dev tools. here is a video to show the case. https://app.screencastify.com/v3/watch/50zMj6cLwJipmPZn22NE
I am no expert on html and css. But i managed to fix it by doing this.
What i want to ask is should i expect any side affects from these changes. Was this a bug or sth i couldn't think of for an edge case?
Hello, I was trying to publish my maui app to appstore but it is rejected. The reason behind is app crashing on startup when it is on release. After I check it up, i understand that reason behind is autofac module. Since it uses reflections and ios doesn't allow it. If you are debugging your app in maui, useinterpreter property is on. So the app is not crashing. There is a discussion over here about the problem. https://github.com/dotnet/maui/issues/13019
But when you switch to release mode since it makes your app slow down, it is turned off and the problem arises. So at the end i decided to create all my httpclient projects as static and remove the autofac from maui app. I had a previous issue that i open a ticket. You can find it here. In that case it was avalonia app. https://support.abp.io/QA/Questions/6476/Problem-using-httpclient-module-in-avalonia-ios-or-xamarin-forms-ios-projects
I managed to fix the issue on almost all appservices. Only problem right now is with authorizationservice. In this line i am getting "no policy found" error.
probably in the background since i removed autofac module authorization service is trying to do the same thing on the web server. It is not intercepted anymore i guess. Is there any way to fix that problem? Also i think maui project shouldn't depend on autofac since intercepting is no no for ios.
Hello, The question is related with Abp Client Proxies. I have a web server which uses abp and abp endpoints. Now i want to share the httpclient module of the web server and use it in avalonia ui project. I created an abp module and do necessary configurations for avalonia project. Added HttpClient project reference. Now when i run the project on android environment it works fine. But when i run it on ios, it throws an exception "platform not supported exception". here is the full exception
System.PlatformNotSupportedException: Dynamic code generation is not supported on this platform.
at System.Reflection.Emit.AssemblyBuilder.ThrowDynamicCodeNotSupported()
at System.Reflection.Emit.AssemblyBuilder.EnsureDynamicCodeSupported()
at System.Reflection.Emit.RuntimeAssemblyBuilder..ctor(AssemblyName n, AssemblyBuilderAccess access)
at System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access)
at Castle.DynamicProxy.ModuleScope.CreateModule(Boolean signStrongName)
at Castle.DynamicProxy.ModuleScope.ObtainDynamicModuleWithWeakName()
at Castle.DynamicProxy.ModuleScope.ObtainDynamicModule(Boolean isStrongNamed)
at Castle.DynamicProxy.ModuleScope.DefineType(Boolean inSignedModulePreferably, String name, TypeAttributes flags)
at Castle.DynamicProxy.Generators.Emitters.ClassEmitter.CreateTypeBuilder(ModuleScope moduleScope, String name, Type baseType, IEnumerable`1 interfaces, TypeAttributes flags, Boolean forceUnsigned)
at Castle.DynamicProxy.Generators.Emitters.ClassEmitter..ctor(ModuleScope moduleScope, String name, Type baseType, IEnumerable`1 interfaces, TypeAttributes flags, Boolean forceUnsigned)
at Castle.DynamicProxy.Generators.Emitters.ClassEmitter..ctor(ModuleScope moduleScope, String name, Type baseType, IEnumerable`1 interfaces)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.BuildClassEmitter(String typeName, Type parentType, IEnumerable`1 interfaces)
at Castle.DynamicProxy.Generators.BaseInterfaceProxyGenerator.Init(String typeName, ClassEmitter& emitter, Type proxyTargetType, FieldReference& interceptorsField, IEnumerable`1 allInterfaces)
at Castle.DynamicProxy.Generators.BaseInterfaceProxyGenerator.GenerateType(String typeName, INamingScope namingScope)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.<>c__DisplayClass13_0.<GetProxyType>b__0(CacheKey cacheKey)
at Castle.Core.Internal.SynchronizedDictionary`2[[Castle.DynamicProxy.Generators.CacheKey, Castle.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc],[System.Type, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].GetOrAdd(CacheKey key, Func`2 valueFactory)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.GetProxyType()
at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, IInterceptor[] interceptors)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionHttpClientProxyExtensions.<>c__DisplayClass4_0.<AddHttpClientProxy>b__1(IServiceProvider serviceProvider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeServiceProviderEngine.<>c__DisplayClass4_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[IScreenAppService](IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionCommonExtensions.GetRequiredService[IScreenAppService](IServiceCollection services)
at Adzup.Player.AbpBootstrapper.GetRequiredService[IScreenAppService]()
at Adzup.Player.ViewModels.ConfigurationViewModel..ctor() in /Users/cangunaydin/projects/Adzup.Player/Adzup.Player/Adzup.Player/ViewModels/ConfigurationViewModel.cs:line 36
so the reason is obvious from the stacktrace. According to microsoft docs for ios, it says:
Since the iOS kernel prevents an application from generating code dynamically, Xamarin.iOS does not support any form of dynamic code generation. These include:
The System.Reflection.Emit is not available.
No support for System.Runtime.Remoting.
No support for creating types dynamically (no Type.GetType ("MyType`1")), although looking up existing types (Type.GetType ("System.String") for example, works just fine).
Reverse callbacks must be registered with the runtime at compile time.
I also find a previous post related with this https://support.abp.io/QA/Questions/2752/SystemPlatformNotSupportedException-when-running-Xamarin-Forms-on-iOS-using-ABP-Module-with-Autofac
so the question is, is it possible to make this work so i can use the httpclient module for my avalonia ios project? And I wonder how does this work for Maui App if it does not support System.Reflection.Emit. It seems like Castle.DynamicProxy class calls System.Reflection.Emit. Is Maui project bypassing this by replacing the service with sth else?
Hello I am having problem with maui application when i do posts to the api. HttpStatusCode:400 returns every time, is sth changed on antiforgery token middleware on version 8?
I didn't have this problem on v7.4.
To reproduce the problem just create a new project from scratch with v8 rc2.
abp new BookStore -t app-pro -u angular -dbms PostgreSQL --separate-auth-server -m maui -csf --preview
then try to run maui app and **create a new user **(or try to do any post or put). you will get an error. Bad Request with status code 400
is there a way to ignore antiforgery token check for mobile app calls only.
Package: "Volo.Abp.TextTemplateManagement.Application.Contracts-v8.0.0-rc.2" is up to date. Package: "Volo.Abp.Gdpr.Application.Contracts-v8.0.0-rc.2" is up to date. Package: "Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX-v3.0.0-rc.1" is up to date. Package: "Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonX-v3.0.0-rc.1" is up to date. Checking installed npm global packages... Checking installed npm global packages... Updated @abp/ng.components to ~8.0.0-rc.2 in /angular/package.json. Updated @abp/ng.core to ~8.0.0-rc.2 in /angular/package.json. Updated @abp/ng.oauth to ~8.0.0-rc.2 in /angular/package.json. One or more errors occurred. (startIndex ('-1') must be a non-negative value. (Parameter 'startIndex') Actual value was -1.) System.AggregateException: One or more errors occurred. (startIndex ('-1') must be a non-negative value. (Parameter 'startIndex') Actual value was -1.) ---> System.ArgumentOutOfRangeException: startIndex ('-1') must be a non-negative value. (Parameter 'startIndex') Actual value was -1. at System.ArgumentOutOfRangeException.ThrowNegative[T](T value, String paramName) at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length) at System.String.Substring(Int32 startIndex, Int32 length) at Volo.Abp.Cli.ProjectModification.NpmPackagesUpdater.ExtractVersions(String output) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\NpmPackagesUpdater.cs:line 357 at Volo.Abp.Cli.ProjectModification.NpmPackagesUpdater.GetPackageVersionList(JProperty package, String workingDirectory) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\NpmPackagesUpdater.cs:line 348 at Volo.Abp.Cli.ProjectModification.NpmPackagesUpdater.GetLatestVersion(JProperty package, Boolean includeReleaseCandidates, Boolean includePreviews, String workingDirectory) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\NpmPackagesUpdater.cs:line 274 at Volo.Abp.Cli.ProjectModification.NpmPackagesUpdater.TryUpdatingPackage(String filePath, JProperty package, Boolean includePreviews, Boolean includeReleaseCandidates, Boolean switchToStable, String specifiedVersion) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\NpmPackagesUpdater.cs:line 238 at Volo.Abp.Cli.ProjectModification.NpmPackagesUpdater.UpdatePackagesInFile(String filePath, Boolean includePreviews, Boolean includeReleaseCandidates, Boolean switchToStable, String specifiedVersion) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\NpmPackagesUpdater.cs:line 179 at Volo.Abp.Cli.ProjectModification.NpmPackagesUpdater.<>c__DisplayClass18_0.<<Update>g__UpdateAsync|0>d.MoveNext() in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\NpmPackagesUpdater.cs:line 83 --- End of inner exception stack trace --- at System.Threading.Tasks.Task.WaitAllCore(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.WaitAll(Task[] tasks) at Volo.Abp.Cli.ProjectModification.NpmPackagesUpdater.Update(String rootDirectory, Boolean includePreviews, Boolean includeReleaseCandidates, Boolean switchToStable, String version) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\NpmPackagesUpdater.cs:line 89 at Volo.Abp.Cli.ProjectModification.PackagePreviewSwitcher.SwitchSolutionsToPreview(List`1 solutionPaths) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\PackagePreviewSwitcher.cs:line 83 at Volo.Abp.Cli.ProjectModification.PackagePreviewSwitcher.SwitchToPreview(CommandLineArgs commandLineArgs) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\ProjectModification\PackagePreviewSwitcher.cs:line 38 at Volo.Abp.Cli.Commands.SwitchToPreviewCommand.ExecuteAsync(CommandLineArgs commandLineArgs) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\Commands\SwitchToPreviewCommand.cs:line 22 at Volo.Abp.Cli.CliService.RunInternalAsync(CommandLineArgs commandLineArgs) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\CliService.cs:line 169 at Volo.Abp.Cli.CliService.RunAsync(String[] args) in D:\ci\Jenkins\workspace\abp-volo-release\abp\framework\src\Volo.Abp.Cli.Core\Volo\Abp\Cli\CliService.cs:line 77
when I try to switch from 7.4.0 to 8.0 preview with abp cli i got this error. Any fix I can do?
Hello when you create a new template with maui. Android app looks ok and working fine. Still some problems on the shell menu with visibility but overall it is okay. But when i try to run the app on ios with physical device or simulator. it looks very bad. here are some screen shots so you can understand what i mean.
dark theme menu: avatar is not displayed good paddings and margins are weird.
dark theme tenants list: when it is empty empty image is overflowing.
dark theme user list: action list not working, empty image problem list is not looking ok.
settings page profile pictures. everything is looking weird.
light theme: search box is black
light theme menu: avatar problem
light theme: all the inputs are looking weird.
the question here is, is this related with maui or theming problem?
Also i realized that when you try to run the app on windows, shell flyout menu have some problems, sometimes menu items are not showing when you sign in and out. Sometimes their order has been mixed. So signout is coming before tenants. I think list is not refreshed so it keeps the buttons as it is.
What can be done to solve these problems? With v8 are the problems gonna be fixed or should i fix everything manually one by one for my project?
Hello, I am using Volo.Payment module and i customized it little bit, only payment provider we use is stripe at the time. So what i want to achieve is, when the user update the plan from stripe dashboard ( modify the payment plan, changing the productid or priceid not only date) I want to be able to modify the necessary things in db. Like finding that tenant and switching to different edition. As i see from PaymentModule
it only gets the value "current_period_end" from the webhook call payload. So PaymentUpdatedEto is not holding those values. and since the method is "private protected virtual" i can not override the method so i can pass extra parameters with the event. How can i solve the problem? should i modify the PaymentRequestAppService instead?
public override async Task<bool> HandleWebhookAsync(string paymentGateway, string payload, Dictionary<string, string> headers)
{
if (paymentGateway=="stripe")
{
//call my service and return
}
await PaymentGatewayResolver.Resolve(paymentGateway).HandleWebhookAsync(payload, headers);
return true;
}
for the next version, is it possible to change private protected methods like "HandleCustomerSubscriptionUpdatedAsync" and "HandleCustomerSubscriptionDeletedAsync" to protected only so it could be overridden.
Hello I want to serve different databases for different tenants and I know abp supports that and have a very good documentation about it. In my case i have a little bit different scenario.
I am building a server that multiple iot devices will hit the server and they are gonna be registered to host database (they do not belong to any tenant at that moment). Then the host tenant administrator needs to assign the devices to one of the tenants in the system from user interface.
So when it is assigned, i need to check if tenant has a separate db connection and according to that i will change the ICurrentTenant and insert a new data to tenant db. Then delete the data from host db. That is my plan. Sth like this.
public async Task ApproveForSeparateDbAsync(ApproveScreenForSeparateDbDto input)
{
var newScreens = new List<Screen>();
var screens = await _screenRepository.GetListByIdsAsync(input.ScreenIds);
using (CurrentTenant.Change(input.TenantId))
{
foreach (var screen in screens)
{
var newScreen = new Screen(GuidGenerator.Create(),
screen.Name,
screen.MacAddress,
screen.DeviceType,
screen.DeviceTypeVersion,
screen.ModelNumber,
screen.ApplicationVersion,
screen.IpAddress,
screen.Port,
screen.CurrentClock,
input.TenantId);
newScreen.Approve(input.TenantId,isSeparateDb:true);
newScreens.Add(newScreen);
}
await _screenRepository.InsertManyAsync(newScreens);
}
foreach (var screen in screens)
{
await _screenManager.DeleteWithEventAsync(screen);
}
}
Screen is a FullAuditedAggregateRoot with IMultiTenant interface.
here is screen constructor.
public Screen(
Guid id,
string name,
string macAddress,
string deviceType,
int deviceTypeVersion,
string modelNumber,
string applicationVersion,
string ipAddress,
int port,
DateTime currentClock,
Guid? tenantId = null) : base(id)
{
Check.NotNullOrWhiteSpace(macAddress, nameof(macAddress));
Check.NotNullOrWhiteSpace(deviceType, nameof(deviceType));
Check.NotNullOrWhiteSpace(modelNumber, nameof(modelNumber));
Check.Positive(deviceTypeVersion, nameof(deviceTypeVersion));
TenantId = tenantId;
UpdateName(name);
MacAddress = macAddress;
DeviceType = deviceType;
DeviceTypeVersion = deviceTypeVersion;
ModelNumber = modelNumber;
UpdateApplicationVersion(applicationVersion);
CurrentClock = currentClock;
IpAddress = ipAddress;
Port = port;
var openingHours = OpeningHoursHelper.GetDefault().Select(o => new OpeningHoursEto()
{
Id = o.Id,
Day = o.Day,
StartTime = o.StartTime,
EndTime = o.EndTime
}).ToList();
AddLocalEvent(new ScreenCreatedEto()
{
Id = id,
Name = name,
MacAddress = macAddress,
TenantId = TenantId,
OpeningHours = openingHours
});
}
you can see that over here i am trying to trigger an event so listeners can do the necessary work. when unitofwork completed it doesn't trigger any event. Weird part is if i do the same by injecting ILocalEventBus to appservice. It triggers the event. and you can see the local events on CurrentUnitOfWork.LocalEventHandlers.
Also if i change
using (CurrentTenant.Change(input.TenantId))
to
using (CurrentTenant.Change(null))
it also triggers the events. I suppose this is some kind of bug or sth i don't know when the current tenant has different Database.
Hello I am trying to find out bottlenecks inside my app with stress testing. I am preparing the server to handle more than 5000 device requests. It is going to be 1 get / post request in every 5 secs for each device. Each device is sending a soap xml format when they do post and when they do get, they are getting a response as xml from the server. To serve xml to device, I use Volo.Abp.TextTemplating.Scriban
I prepare my controllers to connect to database less frequently so i do not create bottleneck in database. To do that i use Microsoft Orleans. Holding the data in memory then saving it to database in every 5 mins since it is not a critical data that comes from the device. However for some critical data sometimes I need to persist the data, this is happening at first request from each device. I use k6 for stress test. I prepared a test for 3000 devices. I also make a setup for pgbouncer in front of postgresql for connection pooling. Things are okay until 2000 devices after this number I am getting this exception.
2023-10-16 22:03:31.077 +02:00 [ERR] The operation was canceled. System.OperationCanceledException: The operation was canceled. at System.Threading.CancellationToken.ThrowOperationCanceledException() at System.Threading.SemaphoreSlim.WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, Int32 millisecondsTimeout, CancellationToken cancellationToken) at Volo.Abp.Threading.SemaphoreSlimExtensions.LockAsync(SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken) at Volo.Abp.Caching.DistributedCache
2.GetOrAddAsync(TCacheKey key, Func
1 factory, Func1 optionsFactory, Nullable
1 hideErrors, Boolean considerUow, CancellationToken token) at Volo.Abp.TextTemplateManagement.TextTemplates.DatabaseTemplateContentContributor.GetOrNullAsync(TemplateContentContributorContext context) at Volo.Abp.TextTemplating.TemplateContentProvider.GetContentOrNullAsync(ITemplateContentContributor[] contributors, TemplateContentContributorContext context) at Volo.Abp.TextTemplating.TemplateContentProvider.GetContentOrNullAsync(TemplateDefinition templateDefinition, String cultureName, Boolean tryDefaults, Boolean useCurrentCultureIfCultureNameIsNull) at Volo.Abp.TextTemplating.TemplateRenderingEngineBase.GetContentOrNullAsync(TemplateDefinition templateDefinition) at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderSingleTemplateAsync(TemplateDefinition templateDefinition, Dictionary2 globalContext, Object model) at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderInternalAsync(String templateName, Dictionary
2 globalContext, Object model) at Volo.Abp.TextTemplating.Scriban.ScribanTemplateRenderingEngine.RenderAsync(String templateName, Object model, String cultureName, Dictionary2 globalContext) at Volo.Abp.TextTemplating.AbpTemplateRenderer.RenderAsync(String templateName, Object model, String cultureName, Dictionary
2 globalContext) at Doohlink.MagicInfo.Envelopes.Renderers.EnvelopeRenderingService1.RenderAsync(EnvelopeHeader header, TModel body) in C:\Development\Projects\Examples\Doohlink\aspnet-core\modules\Doohlink.MagicInfo\src\Doohlink.MagicInfo.Domain\Envelopes\Renderers\EnvelopeRenderingService.cs:line 30 at Doohlink.MagicInfo.Handlers.CommandHandler.HandleAsync(Envelope
1 envelope) in C:\Development\Projects\Examples\Doohlink\aspnet-core\modules\Doohlink.MagicInfo\src\Doohlink.MagicInfo.Application\Handlers\CommandHandler.cs:line 90 at Doohlink.MagicInfo.Handlers.EnvelopeHandler.HandlePostAsync(String body) in C:\Development\Projects\Examples\Doohlink\aspnet-core\modules\Doohlink.MagicInfo\src\Doohlink.MagicInfo.Application\Handlers\EnvelopeHandler.cs:line 62
and after the stress test finished, the application can not connect to redis anymore. i need to flush redis. Also you can see that inside the logs.
2023-10-16 22:42:47.163 +02:00 [WRN] The message timed out in the backlog attempting to send because no connection became available, command=HMGET, timeout: 5000, outbound: 0KiB, inbound: 0KiB, inst: 0, qu: 89, qs: 0, aw: True, bw: CheckingForTimeoutComplete, rs: ReadAsync, ws: Idle, in: 0, in-pipe: 0, out-pipe: 0, last-in: 0, cur-in: 0, sync-ops: 833, async-ops: 49078, serverEndpoint: localhost:6379, conn-sec: 1484.52, aoc: 1, mc: 1/1/0, mgr: 10 of 10 available, clientName: DESKTOP-NHAEDKT(SE.Redis-v2.6.122.38350), IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=47,Free=32720,Min=6,Max=32767), POOL: (Threads=52,QueuedItems=441,CompletedItems=2340351,Timers=7635), v: 2.6.122.38350 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts) StackExchange.Redis.RedisTimeoutException: The message timed out in the backlog attempting to send because no connection became available, command=HMGET, timeout: 5000, outbound: 0KiB, inbound: 0KiB, inst: 0, qu: 89, qs: 0, aw: True, bw: CheckingForTimeoutComplete, rs: ReadAsync, ws: Idle, in: 0, in-pipe: 0, out-pipe: 0, last-in: 0, cur-in: 0, sync-ops: 833, async-ops: 49078, serverEndpoint: localhost:6379, conn-sec: 1484.52, aoc: 1, mc: 1/1/0, mgr: 10 of 10 available, clientName: DESKTOP-NHAEDKT(SE.Redis-v2.6.122.38350), IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=47,Free=32720,Min=6,Max=32767), POOL: (Threads=52,QueuedItems=441,CompletedItems=2340351,Timers=7635), v: 2.6.122.38350 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts) at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor
1 processor, ServerEndPoint server, T defaultValue) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 2099 at StackExchange.Redis.RedisDatabase.HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags flags) in /_/src/StackExchange.Redis/RedisDatabase.cs:line 405 at Microsoft.Extensions.Caching.StackExchangeRedis.RedisExtensions.HashMemberGet(IDatabase cache, String key, String[] members) at Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache.GetAndRefresh(String key, Boolean getData) at Volo.Abp.Caching.DistributedCache
2.Get(TCacheKey key, Nullable`1 hideErrors, Boolean considerUow) 2023-10-16 22:42:47.163 +02:00 [WRN] ---------- Exception Data ---------- Redis-Message = HMGET c:Volo.Abp.LanguageManagement.Texts,k:Adzup:AbpExceptionHandling_en Redis-Timeout = 5000 Redis-Write-State = Idle Redis-Read-State = ReadAsync Redis-OutboundDeltaKB = 0KiB Redis-InboundDeltaKB = 0KiB Redis-OpsSinceLastHeartbeat = 0 Redis-Queue-Awaiting-Write = 89 Redis-Queue-Awaiting-Response = 0 Redis-Active-Writer = True Redis-Backlog-Writer = CheckingForTimeoutComplete Redis-Inbound-Bytes = 0 Redis-Inbound-Pipe-Bytes = 0 Redis-Outbound-Pipe-Bytes = 0 Redis-Last-Result-Bytes = 0 Redis-Inbound-Buffer-Bytes = 0 Redis-Sync-Ops = 833 Redis-Async-Ops = 49078 Redis-Server-Endpoint = localhost:6379 Redis-Server-Connected-Seconds = 1484.52 Redis-Abort-On-Connect = 1 Redis-Multiplexer-Connects = 1/1/0 Redis-Manager = 10 of 10 available Redis-Client-Name = DESKTOP-NHAEDKT(SE.Redis-v2.6.122.38350) Redis-ThreadPool-IO-Completion = (Busy=0,Free=1000,Min=1,Max=1000) Redis-ThreadPool-Workers = (Busy=47,Free=32720,Min=6,Max=32767) Redis-ThreadPool-Items = (Threads=52,QueuedItems=441,CompletedItems=2340351,Timers=7635) Redis-Busy-Workers = 47 Redis-Version = 2.6.122.38350 redis-command = HMGET c:Volo.Abp.LanguageManagement.Texts,k:Adzup:AbpExceptionHandling_en request-sent-status = WaitingInBacklog redis-server = localhost:6379
So couple of questions, - I understand from the exception that it is trying to get the template text from DatabaseTemplateContentContributor, at Volo.Abp.TextTemplateManagement.TextTemplates.DatabaseTemplateContentContributor.GetOrNullAsync(TemplateContentContributorContext context) I assume this is coming from Text Template Management Module (https://docs.abp.io/en/commercial/latest/modules/text-template-management#text-template-management-module) and since this is the last contributor, it is the first to try.
Since my text templates doesn't use any localization is it possible to use VirtualFileTemplateContentContributor instead? Of course I can add another ITemplateContentContributor. I just wonder if there is any other way to avoid trying the last contributor and only use VirtualFileTemplateContentContributor, since I don't want the code to go to redis cache or database at all. All I need is to get the template from virtual file system and replace it with the model.
- Also I wonder what is happening in this setup, Is the bottleneck happening from the redis cache or from the database connection? At first thought, I assume it is sth going on with Redis Cache, Cause if the templates are cached, it won't go to database after some time for the same template. But strange thing over here is if i increase the connection pool size in database, I can increase the concurrent users that the server handles. With 150 max connections and max pool size of 150 i can handle 2000 users, if i increase the pool size to 250 then the server can handle 3000 users with the same test. So it seems database connection pool has a role over here, but I am not expecting for the code to create a connection with database. Why it is happening? Can it be a bug when it tries to get the template from the cache? so it goes to database instead?
By the way I disabled auditlogging all over the application with this configuration. any help would be appreciated.
Configure<AbpAuditingOptions>(options =>
{
options.IsEnabled = false; //Disables the auditing system
});
Hello, I think razor text templating have a memory leak. And i suppose it is sth. with caching. To produce the problem here are the steps, I can also send a sample app for this.
abp new Acme.BookStore -u none -csf
abp add-package Volo.Abp.TextTemplating.Razor
public class Command
{
public bool ReportIndicate { get; set; }
public string CommandId { get; set; }
public string MoCmd { get; set; }
public MoSequence MoSequence { get; set; }
public Command()
{
}
public Command(bool reportIndicate, string commandId, string moCmd, MoSequence moSequence)
{
Check.NotNullOrWhiteSpace(commandId, nameof(commandId));
Check.NotNullOrWhiteSpace(moCmd, nameof(moCmd));
Check.NotNull(moSequence, nameof(moSequence));
ReportIndicate = reportIndicate;
CommandId = commandId;
MoCmd = moCmd;
MoSequence = moSequence;
}
}
public class MoSequence
{
public List<Mo> MoList { get; set; }
public MoSequence()
{
MoList = new List<Mo>();
}
public void AddMo(string moPath, string moValue)
{
MoList.Add(new Mo(moPath, moValue));
}
public void AddMo(string moPath)
{
MoList.Add(new Mo(moPath));
}
}
public class Mo
{
public string MoPath { get; set; }
public string MoValue { get; set; }
public Mo()
{
}
public Mo(string moPath)
{
MoPath = moPath;
}
public Mo(string moPath, string moValue)
{
MoPath = moPath;
MoValue = moValue;
}
}
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Acme.BookStore.Models.Command>
<srm:COMMAND>
<srm:REPORT_INDICATE>@(Model.ReportIndicate ? "true" : "false")</srm:REPORT_INDICATE>
<srm:COMMAND_ID>@Model.CommandId</srm:COMMAND_ID>
<srm:MO_CMD>@Model.MoCmd</srm:MO_CMD>
<srm:MO_SEQUENCE>
@foreach (var item in Model.MoSequence.MoList)
{
<srm:MO>
<srm:MO_PATH>@item.MoPath</srm:MO_PATH>
@if (item.MoValue != null)
{
<srm:MO_VALUE>@item.MoValue</srm:MO_VALUE>
}
else
{
<srm:MO_VALUE />
}
</srm:MO>
}
</srm:MO_SEQUENCE>
</srm:COMMAND>
public class DemoTemplateDefinitionProvider : TemplateDefinitionProvider
{
public override void Define(ITemplateDefinitionContext context)
{
context.Add(
new TemplateDefinition("Demo") //template name: "Demo"
.WithRazorEngine()
.WithVirtualFilePath(
"/Template/Demo.cshtml", //template content path
isInlineLocalized: true
)
);
}
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<BookStoreApplicationModule>();
});
Configure<AbpRazorTemplateCSharpCompilerOptions>(options =>
{
options.References.Add(MetadataReference.CreateFromFile(typeof(BookStoreApplicationModule).Assembly.Location));
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<BookStoreApplicationModule>("Acme.BookStore");
});
}
7) Create an appservice that will return the output.
public class TestAppService : BookStoreAppService, ITestAppService
{
private readonly ITemplateRenderer _templateRenderer;
public TestAppService(ITemplateRenderer templateRenderer)
{
_templateRenderer = templateRenderer;
}
public async Task<string> GetOutput()
{
var moSequence = new MoSequence();
moSequence.AddMo(".MO.MONITOR_OPERATION.BOOTSTRAP.DEV_CODE", "105");
moSequence.AddMo(".MO.MONITOR_OPERATION.BOOTSTRAP.DEV_TYPE", "SPLAYER" + Random.Shared.Next().ToString());
moSequence.AddMo(".MO.MONITOR_OPERATION.BOOTSTRAP.DEV_MDNM", "QB13R");
var command = new Command(false,
"31470ade5bc2fd42-60c7af5-4725-8703-33dd729f63cea7aa5e4fbc0e",
".MO.MONITOR_OPERATION.BOOTSTRAP",
moSequence);
var result = await _templateRenderer.RenderAsync(
"Demo", //the template name
command
);
return result;
}
}
<srm:COMMAND>
<srm:REPORT_INDICATE>false</srm:REPORT_INDICATE>
<srm:COMMAND_ID>31470ade5bc2fd42-60c7af5-4725-8703-33dd729f63cea7aa5e4fbc0e</srm:COMMAND_ID>
<srm:MO_CMD>.MO.MONITOR_OPERATION.BOOTSTRAP</srm:MO_CMD>
<srm:MO_SEQUENCE>
<srm:MO>
<srm:MO_PATH>.MO.MONITOR_OPERATION.BOOTSTRAP.DEV_CODE</srm:MO_PATH>
<srm:MO_VALUE>105</srm:MO_VALUE>
</srm:MO>
<srm:MO>
<srm:MO_PATH>.MO.MONITOR_OPERATION.BOOTSTRAP.DEV_TYPE</srm:MO_PATH>
<srm:MO_VALUE>SPLAYER737483572</srm:MO_VALUE>
</srm:MO>
<srm:MO>
<srm:MO_PATH>.MO.MONITOR_OPERATION.BOOTSTRAP.DEV_MDNM</srm:MO_PATH>
<srm:MO_VALUE>QB13R</srm:MO_VALUE>
</srm:MO>
</srm:MO_SEQUENCE>
</srm:COMMAND>
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
insecureSkipTLSVerify: true,
noConnectionReuse: false,
scenarios: {
per_vu_scenario: {
executor: "per-vu-iterations",
vus: 5,
iterations: 30,
startTime: "0s",
maxDuration: '2m',
},
},
};
export default function () {
// Here, we set the endpoint to test.
const response = http.get('https://localhost:44395/api/app/test/output');
// An assertion
check(response, {
'is status 200': (x) => x.status === 200
});
sleep(3);
}
k6 run load.js
and check the memory spike in dotmemory you will see sth similar like this.
I analyze this with dotnet-dump and dotmemory. It has lots of free memory in unmanaged memory heap. mostly strings. I didn't check the source code. It could be sth wrong from caching so it caches the same thing in every request, but not sure, didn't deep dive into it.
If i switch to Volo.Abp.TextTemplating.Scriban, this doesn't happen and you can see the memory steady, no spikes. I switch to scriban and change all my templates with it. Hope i could clarify the problem if you need a sample app i can send it if you give an email address.