Base solution for your next web application
Ends in:
01 DAYS
01 HRS
01 MIN
01 SEC

Activities of "lojelis"

Hi @ismcagdas,

Here is the specifications of my computer (sorry it's in french but I think you can understand the main parts):

I have used the Stopwatch Class from System.Diagnostics to measure the execution time of the Intialize method from the AbpBootstrapper class, but I haven't been in depth into the Initialize method. How can I measure the execution times of the method calls inside the method Initialize?

Thanks in advance,

Nicolas

Yes I can, here it is:

using System;
using System.IO;
using Abp;
using Abp.AspNetZeroCore;
using Abp.AutoMapper;
using Abp.Configuration.Startup;
using Abp.Dependency;
using Abp.Modules;
using Abp.Net.Mail;
using Abp.TestBase;
using Abp.Zero.Configuration;
using Castle.MicroKernel.Registration;
using Microsoft.Extensions.Configuration;
using Lojelis.COPYlote.Authorization.Users;
using Lojelis.COPYlote.Configuration;
using Lojelis.COPYlote.EntityFrameworkCore;
using Lojelis.COPYlote.MultiTenancy;
using Lojelis.COPYlote.Security.Recaptcha;
using Lojelis.COPYlote.Tests.Configuration;
using Lojelis.COPYlote.Tests.DependencyInjection;
using Lojelis.COPYlote.Tests.UiCustomization;
using Lojelis.COPYlote.Tests.Url;
using Lojelis.COPYlote.Tests.Web;
using Lojelis.COPYlote.UiCustomization;
using Lojelis.COPYlote.Url;
using NSubstitute;
using Lojelis.COPYlote.App;
using Lojelis.COPYlote.Tests.App.UserHelper;

namespace Lojelis.COPYlote.Tests
{
    [DependsOn(
        typeof(COPYloteApplicationModule),
        typeof(COPYloteEntityFrameworkCoreModule),
        typeof(AbpTestBaseModule))]
    public class COPYloteTestModule : AbpModule
    {
        public COPYloteTestModule(COPYloteEntityFrameworkCoreModule abpZeroTemplateEntityFrameworkCoreModule)
        {
            abpZeroTemplateEntityFrameworkCoreModule.SkipDbContextRegistration = true;
        }

        public override void PreInitialize()
        {
            var configuration = GetConfiguration();

            Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);
            Configuration.UnitOfWork.IsTransactional = false;
            //Configuration.UnitOfWork.OverrideFilter("MayHaveSite",false);

            //Disable static mapper usage since it breaks unit tests (see https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2052)
            Configuration.Modules.AbpAutoMapper().UseStaticMapper = false;

            //Use database for language management
            Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();

            RegisterFakeService<AbpZeroDbMigrator>();

            IocManager.Register<IAppUrlService, FakeAppUrlService>();
            IocManager.Register<IWebUrlService, FakeWebUrlService>();
            IocManager.Register<IRecaptchaValidator, FakeRecaptchaValidator>();
            IocManager.Register<IUserHelper, FakeUserHelper>();

            Configuration.ReplaceService<IAppConfigurationAccessor, TestAppConfigurationAccessor>();
            Configuration.ReplaceService<IEmailSender, NullEmailSender>(DependencyLifeStyle.Transient);

            Configuration.ReplaceService<IUiThemeCustomizerFactory, NullUiThemeCustomizerFactory>();

            Configuration.Modules.AspNetZero().LicenseCode = configuration["AbpZeroLicenseCode"];

            //Uncomment below line to write change logs for the entities below:
            Configuration.EntityHistory.IsEnabled = true;
            Configuration.EntityHistory.Selectors.Add("COPYloteEntities", typeof(User), typeof(Tenant));
        }

        public override void Initialize()
        {
            ServiceCollectionRegistrar.Register(IocManager);
        }

        private void RegisterFakeService<TService>()
            where TService : class
        {
            IocManager.IocContainer.Register(
                Component.For<TService>()
                    .UsingFactoryMethod(() => Substitute.For<TService>())
                    .LifestyleSingleton()
            );
        }

        private static IConfigurationRoot GetConfiguration()
        {
            return AppConfigurations.Get(Directory.GetCurrentDirectory(), addUserSecrets: true);
        }
    }
}

I can't share the project because I have confidentiality engagements with my client. However I have discovered that some other ABP users had the issue in the past: https://support.aspnetzero.com/QA/Questions/444.

That's exactly my case. I have studied more in details the problem and it comes from the class AbpBootstrapper and its method Initialize.

Did you find a solution in the past?

Best regards, Nicolas

Another relevant piece of code. The following takes 2 minutes to run:

public abstract class AppTestBase : AbpIntegratedTestBase<COPYloteTestModule>
{
     protected AppTestBase() : base(true, null)
     {
     }
 }
 
public class Hello_Test : AppTestBase
{
   [Fact]
    public void Should_Write_Hello_World()
    {
        Console.WriteLine("Hello World");
    }
}

While this takes 182ms:

public abstract class AppTestBase : AbpIntegratedTestBase<COPYloteTestModule>
{
     protected AppTestBase() : base(false, null)
     {
     }
 }
 
public class Hello_Test : AppTestBase
{
   [Fact]
    public void Should_Write_Hello_World()
    {
        Console.WriteLine("Hello World");
    }
}

The only difference is the parameter initializeAbp of the base class AbpIntegratedTestBase which is turned to false.

So what can slow down ABP initialization? Is it the total number of app services in the project? Currently we have 70 services. With :

  • 173 GET methods
  • 158 POST methods
  • 43 PUT methods
  • 26 DELETE methods

Which makes 400 endpoints. Maybe the initialization is slow because of this? Have you ever try to use ABP for a project of this size (or even bigger)?

Best regards, Nicolas

Hi thanks for your reply!

I am requisting the autorisation from my hierachy to share the project with you. While I am waiting for the answer, I can share some small pieces of code to give you some clues.

 public abstract class AppTestBase : AbpIntegratedTestBase<COPYloteTestModule>
 {
    protected AppTestBase() : base(true, null)
    {
        //SeedTestData();
        //LoginAsDefaultTenantAdmin();
    }
 }

I have voluntary commented the two lines to see if the performance issue does not come from here but without success. The test still take 2 minutes to run. Here is the prototype of our test class:

    public class EmployeService_Tests : AppTestBase
    {
        [Fact]
        public async void Should_Get_All_The_Employees()
        {
            var employes = await _employeService.GetAllAsync();
            Assert.Equal(5, employes.Items.Count);
        }
    }

Regards, Nicolas

Showing 1 to 5 of 5 entries