Long running context in Web Server (ASP.NET MVC)?

10 posts, 0 answers
  1. Kendall Bennett
    Kendall Bennett avatar
    80 posts
    Member since:
    Feb 2010

    Posted 19 Apr 2011 Link to this post

    Hi,

    I am investigating using OpenAccess ORM for our new ORM tool to replace our direct ADO.NET SQL code. I have the Open Access ASK installed and I have looked at the ASP.NET MVC Forums sample application. In this application when it creates the ContextFactory class, it is created using the Unity IOC container with a ContainerControllerLifetimeManager(). This means that only one ContextFactory instance is created for the life of the application, and hence only one OpenAccessContext() is created and it lasts for the life of the application.

    I tested this and verified that is true with the ASP.NET development server, and it would seem this would be a very efficient way of handling access to the database, as only one context is actually created. However how does this work when the application is deployed on a real IIS web server, for a high load site? If the site load goes up, doesn't IIS create new threads within the Application Pool in order to be able to service more requests? When that happens does a new thread get started that runs on the same HttpApplication instance, or does IIS create an entirely new HttpApplication instance for every server thread in the application pool?

    It seems to me that if the methods used in the sample program work in production, that IIS must be creating an entirely new HttpApplication per thread? Since I assume OpenAccess ORM is not thread safe, like most other .NET libraries? Or am I missing something entirely?
  2. Serge
    Admin
    Serge avatar
    375 posts

    Posted 21 Apr 2011 Link to this post

    Hi Kendall Bennett,

    Let me shed some light on the situation, when using the context object an internal static database object is created that holds the information for the model. One database object will server as the basis for more than one context. Meaning that a couple of context instances will use the same internal database object.

    This is done because the metadata information describing your model is further calculated and this is not a lightweight operation.

    However, there is more to the situation. Whenever a context is created it holds a cache of all the objects it is tracking. Usually the suggested practice is to have a context live as long as a request, given that the context is pretty lightweight this is okay (the slow operation is handled in the database object creation).

    The problem one might face with a context that is serving more than one request is that it will retrieve object from its cache and not the database. So if there is another thread or application doing the same and modifying data, you might end up with invalid data.

    I will suggest sticking to short living context instances that are created per request and having a look at our L2 cache mechanism. You can find more information on how to enable that on this help article.

    I am not sure if that fully answers your question so please do not hesitate to let us know if you need more information on the matter.

    Regards,
    Serge
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. DevCraft banner
  4. Kendall Bennett
    Kendall Bennett avatar
    80 posts
    Member since:
    Feb 2010

    Posted 21 Apr 2011 Link to this post

    I did some more research and indeed there is always one HttpApplication created per server thread, so anything that is stored in the application globally will only ever be used by one thread at a time (and each thread will only ever process one HttpRequest at a time also, so it won't be shared across requests). Hence it is safe enough to store a global context in the application, and then only one context will be created for the life of that HttpApplication instance which is more efficient than creating a new context for every page request (I understand that context creation is fast, but not doing it all is faster :).

    Thanks for the reply!
  5. Kendall Bennett
    Kendall Bennett avatar
    80 posts
    Member since:
    Feb 2010

    Posted 21 Apr 2011 Link to this post

    Well I have done some more research, and I think the way the MVC forum sample application is written is actually incorrect, and could cause problems in a production environment. As I pointed out above, there is indeed multiple HttpApplication's that are created on the server to handle incoming threads, however the Application_Started() function is ONLY called one time, when the application first starts up. It is not called when each new instance of HttpApplication is created. It also appears that the HttpApplication may actually get called on a different thread (managed thread that is) to the one that was originally used to create it, but it does appear that for every concurrent request handled by the server, there will be a separate HttpApplication instance.

    The problem is that since the sample application simple creates one long running context when the Application_Stated() function is called (because that is when the UnityContainer is created), the exact same ORM context is going to be used by ALL HttpApplication instances, and if at some point two concurrent requests are processed, there will be issues when they are both using the same ORM context.

    I am not sure what the correct solution is, other than changing the controller factory to serve up a new ORM context for every thread. Any suggestions on how to fix this correctly?
  6. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 22 Apr 2011 Link to this post

    Hi Kendall Bennett,

     You are completely correct, having a long running scope is a bad practice in web environment and we have pointed that previously in some of our KB articles and blog posts. The context must be created and disposed of on each request to the web server in order to be sure that there will be no threading issues with your data access. I will point you now to a blog post that was written some time ago, and it discusses the IObjectScope which is an old API, but you can look at this object as the context - it basically has the same role in the product - just the API is older. Here is a link to this blog post. The focus in this post are actually the ASP .NET web forms and not ASP .NET MVC, but I hope you can get the main idea from it and utilize the approach in your application without limiting yourself by the platform that you use.

    Regards,
    Zoran
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  7. Kendall Bennett
    Kendall Bennett avatar
    80 posts
    Member since:
    Feb 2010

    Posted 22 Apr 2011 Link to this post

    Ok great. So my point in my post above is accurate, that the ASP.NET MVC sample program you distribute is wrong, and should be re-written. When I look at a sample program that is similar to something I am working on, I expect to see Best Practices implemented, so I am surprised nobody has fixed this sample program yet?

    Specifically the sample program goes to the extend of using a context factory class and interface to it to abstract away from the actual creation of the context, however the context is only created ONCE in the lifetime of the context factory, and is also cached in all the respository instances. And since the IoC container has been set up to keep only one context factory around for the life of the IoC container (which is the lifetime of the entire application, not an application instance), then the context is going to be identical for EVERY request processed.

    It would appear from my understanding of the Unity container, that the repositories are created on demand every time someone needs one, and probably only hang around per request. So the fix for this program as I see it, is to somehow make the context factory only hang around for the life of a single request (request scope in Ninject for instance), so that every request would get their own copy of the context factory.
  8. Serge
    Admin
    Serge avatar
    375 posts

    Posted 27 Apr 2011 Link to this post

    Hello Kendall Bennett,

     You are perfectly write. I would like to thank you for leading us to this rather unpleasant error in the MVC Forum sample. We most certainly be fixing this problem and handling the context lifetime per request. I hope in the next release of the SDK that this matter will be resolved. 

    Please find you Telerik Points updated. 

    Best wishes,
    Serge
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  9. Kendall Bennett
    Kendall Bennett avatar
    80 posts
    Member since:
    Feb 2010

    Posted 27 Apr 2011 Link to this post

    Great. I look forward to seeing the updated sample.
  10. Matthew
    Matthew avatar
    13 posts
    Member since:
    Aug 2010

    Posted 12 May 2011 Link to this post

    I've been using NHibernate as my ORM and was hoping to switch over to OpenAccess.  I've been trying to research how best to implement OpenAccess in MVC and came up short till I found this forum posting.  Any ideas on when the next release of the SDK might be?  Or perhaps are there any blog entries I missed that might discuss how to implement this in a real world MVC project?
  11. Serge
    Admin
    Serge avatar
    375 posts

    Posted 14 May 2011 Link to this post

    Hi Matthew,

     We are planning on releasing the next version of our SDK with our SP1, however we do not have an exact timeframe for this that I can share with you. 

    Fortunately the MVC example has only one flaw and this is that the context object is alive as long as the application is alive which is something that we have discussed here and you should be able to work around. 

    Also given that OpenAccess is pretty easy to get started with (you can have a look at our Fluent Mapping Getting started tutorial) and the great tutorials over at asp.net/mvc you should have too much trouble kick-starting a project. 

    You can also rely on us to give you any and all advice that you might need in order to get your application up and running. 

    We are looking forward to hearing back from you.

    Regards,
    Serge
    the Telerik team
    Q1’11 SP1 of Telerik OpenAccess is available for download; also available is the Q2'11 Roadmap for Telerik OpenAccess ORM.
Back to Top
DevCraft banner