4

We are seeing a steady memory growth on our Sitecore 8.2 update 1 application. We had AUTOFAC DI previously and have been completely replaced with Sitecore OOB MS DI.

We followed some guidance from blog post below in order to make sure that Pipeline Processors respects the Scoped lifetime. https://www.coreysmith.co/sitecore-dependency-injection-scoped-services/

RESULT:

The CPU is a lot better with the Sitecore OOB DI container. However, slight memory growth still exists.

I'm expecting that after a certain period of load test the memory should stabilize and should drop down once the load test is stopped. But it's not happening:

enter image description here

Memory Dump shows IDisposable collection holding lots of SitecoreRequestScopeModule. _transientDisposables private collection of Microsoft.Extensions.DependencyInjection.ServiceProvider class

enter image description here

Service Configuration:

public void Configure(IServiceCollection serviceCollection)
{
    //For getting a SitecoreService for any database
    serviceCollection.AddSingleton<Func<Database, ISitecoreService>>(_ => CreateSitecoreService);

    serviceCollection.AddScopedWithFuncFactory<ISitecoreService>(_ => CreateSitecoreContextService());


    serviceCollection.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()
        .Where(assembly => assembly.GetName().Name.Contains("Digital")).ToArray());


    serviceCollection.AddScopedWithFuncFactory<ILoggerService>(c => new LoggerService(_Constants.WebLoggerName));

}

private static T Get<T>()
{
    return ServiceLocator.ServiceProvider.GetService<T>();
}

private static ISitecoreService CreateSitecoreContextService()
{
    var sitecoreServiceThunk = Get<Func<Database, ISitecoreService>>();
    return sitecoreServiceThunk(global::Sitecore.Context.Database);
}

private static ISitecoreService CreateSitecoreService(Database database)
{
    return new SitecoreService(database);
}

Pipeline Processor Injection:

public class AssignQuotationSession : RequestBeginProcessor
    {
        protected readonly Func<ILoggerService> _scopeLoggerService;
        private readonly Func<ISitecoreService> _scopeSitecoreService;

        public AssignQuotationSession(Func<ILoggerService> loggerService, Func<ISitecoreService> SitecoreService)
        {
            _scopeLoggerService = loggerService;
            _scopeSitecoreService = SitecoreService;
        }

        public override void Process(RequestBeginArgs args)
        {
            Assert.ArgumentNotNull(args, "args");            

            var loggerService = _scopeLoggerService();
            var sitecoreService = _scopeSitecoreService();
            ....
            }
}

Sitecore Service that wraps Glass SitecoreService

public class SitecoreService : IContentService, IDisposable
    {
        private readonly ISitecoreService _context;

        /// <summary>
        /// Initializes a new instance of the <see cref="SitecoreRepository"/> class.
        /// </summary>
        /// <param name="context">Sitecore context.</param>
        public SitecoreService(ISitecoreService context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            this._context = context;
        }

        public TModel GetEntity<TModel>(string identity) where TModel : class
        {
            return this._context.GetItem<TModel>(identity);
        }

        public void Dispose()
        {
            _context.Dispose();
        }
}

Any suggestion on what we may be doing wrong here?
This thread talks about the potential cause: https://github.com/aspnet/AspNetCore/issues/5496 https://github.com/aspnet/DependencyInjection/issues/456

Not too sure if we need to create a scope first and wrap it in a using statement. I've been told that SitecoreRequestScopeModule will do all cleanup. But it doesn't look like it...

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.