1

We have multi-step form hosted in sitecore 8.2. As user fills up each step and click on next, our custom pipeline gets invoked. For each steps we have corresponding pipelines. Each pipeline updates the session data as user progresses.

Problem:

During performance test, we noticed that if a user clicks the next button exactly at same time the their session data gets overwritten with other user's data.

Came across this blog post which talks about Processors being Singlon Lifecycle: https://ctor.io/be-careful-with-sitecore-pipeline-processors-lifecycle/

Questions:

Why pipelines are designed to be singleton lifecycle? This issue only occurs if more than 1 user happens the click next button exactly at same time.

Code snippet

namespace MyPipeline
{
    public class Initialize
    {
        private readOnly ISessionStore _sessionStore;

        public Initialize(ISessionStore sessionStore)
        {
            this._sessionStore = sessionStore;
            Sitecore.Diagnostics.Log.Info("ctor() has been called", this);
        }

        public override void Process(EmployeePipelineArgs args)
        {

            _sessionStore.SetSessionData(EmployeePipelineArgs);

        }
    }
}

namespace MyPipeline
{
    public class SessionTest
    {
        private readOnly ISessionStore _sessionStore;

        public LifecycleTest(ISessionStore sessionStore)
        {
            this._sessionStore = sessionStore;
            Sitecore.Diagnostics.Log.Info("ctor() has been called", this);
        }

        public override void Process(CustomPipelineArgs args)
        {
            var mySessionData = _sessionStore.GetSessionData()
            Sitecore.Diagnostics.Log.Info(mySessonData.Name);

        }
    }
}

Snippet for SetSessionData

 public class SessionStore : ISessionStore
{
    private readonly IHttpContextWrapper _httpContext;

    public SessionStore(IHttpContextWrapper httpContext)
    {
         _httpContext = httpContext;
    }

    public override void SetSessionData(data)
    {

        _httpContext.Current.Session[somekey] = data;
    }
}


public class HttpContextWrapper : IHttpContextWrapper
{
    public HttpRequest Request =>  HttpContext.Current.Request;
    public HttpResponse Response => HttpContext.Current.Response;
    public HttpContext Current => HttpContext.Current;
}

Configuration

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      </pipelinetest>
        <processor type="MyPipeline.Initialize, MyPipeline" resolve ="true" />
        <processor type="MyPipeline.SessionTest, MyPipeline" resolve ="true" />     
      </pipelinetest>

    </pipelines>
  </sitecore>
</configuration>

Thanks.

3
  • Can you please share your code snippet – Hishaam Namooya Jan 31 '19 at 5:10
  • And what is the code of ISessionStore method SetSessionData? – Marek Musielak Jan 31 '19 at 7:33
  • 2
    Try and narrow this down to a single concrete question, please. – Mark Cassidy Jan 31 '19 at 8:16
5

I don't think anyone can answer question Why pipelines are designed to be singleton lifecycle? except from whoever came with idea of Sitecore pipelines.

From my understanding, pipelines are used in Sitecore everywhere. In most crucial parts of Sitecore, where even milliseconds matter. Creating new object for every single processor when any pipeline is started would be just waste of time.

In my opinion, pipeline processors should be kind of "stateless". They shouldn't have any single-execution-specific data in their properties. Everything they work on should be passed via arguments of the Process method.

I would expect that your ISessionStore uses something like HttpContext.Current.Session everytime it sets or gets something from session. But if you've created a Session property in ISessionStore and set the value of it to session from httpcontext, then the problem is here. I cannot tell this for sure without seeing the code of your ISessionStore implementation.

8
  • Thanks @Marek, I've updated with SessionStore snippet. Some reason it only happens when more than one user clicks the button exactly same time. If it was singleton issue, I would think it should happen on all scenarios where more than one user are filling the forms. – Nil Pun Feb 1 '19 at 7:14
  • is _httpContext a property in ISessionStore? – Marek Musielak Feb 1 '19 at 7:32
  • updated with SessionStore code snipped @Marek – Nil Pun Feb 4 '19 at 1:22
  • With singleton objects and properties on them you'll have race conditions all the time. Pass ISessionStore via EmployeePipelineArgs instead of setting it as a property on your processors and it should work just fine. – Marek Musielak Feb 4 '19 at 7:28
  • I see, so initialize class will be created as singleton via sitecore configuration factory? If so why issue doesn't occur on all instances where more than users are filling form? – Nil Pun Feb 4 '19 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.