New Posts New Posts RSS Feed: ASP.NET:  Storing PersistenceManager instance in Session vs. Application
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

ASP.NET: Storing PersistenceManager instance in Session vs. Application

 Post Reply Post Reply
Author
pnschofield View Drop Down
Newbie
Newbie
Avatar

Joined: 14-Sep-2007
Location: United States
Posts: 18
Post Options Post Options   Quote pnschofield Quote  Post ReplyReply Direct Link To This Post Topic: ASP.NET: Storing PersistenceManager instance in Session vs. Application
    Posted: 08-Oct-2007 at 1:16pm
I noticed that the tutorial ASP.NET application stores an instance of the PersistenceManager in each user's Session.  Is there a security/threading issue with sharing a single PersistenceManager instance in the Application rather than having an instance for each user?  For my application, I'm concerned that scalability might be an issue if I had thousands of users and therefore thousands of instances of PersistenceManager in memory simultaneously so I'd like to have all users share a single instance if that's possible.

Paul Schofield
Back to Top
davidklitzke View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 14-Jun-2007
Posts: 715
Post Options Post Options   Quote davidklitzke Quote  Post ReplyReply Direct Link To This Post Posted: 08-Oct-2007 at 3:33pm
  • Do not use the Default Persistence Manager in Web Applications.  This is because the Default Persistence Manager is defined in a static class, and therefore all sessions will share the Default Persistence Manager.  Using the Default Persistence Manager in Web Applications will cause unexpected behavior in your application
  • Create a separate new instance of the Persistence Manager for each session
  • Store the newly created Persistence Manager in Session for later use by the application session:
  • Storing a Persistence Manager per session will ensure that the sessions will not interfere with one another's data
Back to Top
Linguinut View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Jun-2007
Location: United States
Posts: 394
Post Options Post Options   Quote Linguinut Quote  Post ReplyReply Direct Link To This Post Posted: 09-Oct-2007 at 9:31am
What kind of performance issues should Paul expect from the abundance of persistence managers in his web application?
Back to Top
jeffdoolittle View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Jun-2007
Location: United States
Posts: 146
Post Options Post Options   Quote jeffdoolittle Quote  Post ReplyReply Direct Link To This Post Posted: 09-Oct-2007 at 9:49am
Paul,

I can't speak to the performance overhead, but I can speak a bit more on  why you have to do it this way.

I tend to think of this in terms of a standard ADO.NET dataset (which, after all, is what a Persistence Manager encapsulates).  In any web application, you're not going to want to have one ADO.NET data set that is shared among all website visitors.  Instead, you're going to instantiate, populate and persist one per user session.  The same holds true when you're using Persistence Managers.

So I don't know if I'd categorize a necessity as a performance issue.  You may be able to optimize things, but you can't get around it.

--Jeff



Edited by jeffdoolittle - 10-Oct-2007 at 11:49pm
Back to Top
pnschofield View Drop Down
Newbie
Newbie
Avatar

Joined: 14-Sep-2007
Location: United States
Posts: 18
Post Options Post Options   Quote pnschofield Quote  Post ReplyReply Direct Link To This Post Posted: 09-Oct-2007 at 9:50am
What kind of performance issues should Paul expect from the abundance of persistence managers in his web application?


Every object stored in the Session (using the InProc Session Store) will utilize system memory on the web server even after the user's request is processed, which is why it's considered a best practice to avoid using session state whenever possible.  Imagine having multiple PMs, each with their own Cache filling up with mostly redundant copies of data as multiple users hit the site.

Ideally, memory utilization on a web server should not increase as the number of simultaneous users increases, except in proportion to the number of threads that process requests simultaneously. 

I think an alternative to using Session would be to use the ASP.NET Cache to store PMs.  That would allow the runtime to dispose of PMs as needed under low memory conditions, which would solve the scalability problem and keep my web host off my back.  The cost would be the occasional need to spin up a new PM in the middle of a user's session, but this is probably less expensive that trying to serialize/deserialize PMs to an out-of-process Session service. In my hosted environment (DiscountASP.NET), I have the option of using SQL Server for session management, but I would need to know that each instance of PM could be serialized for storage in SQL Server in between page requests, and then deserialized on the next request from a user.

What kind of problems have users encountered when sharing a single Persistence Manager? 



Edited by pnschofield - 09-Oct-2007 at 11:02am
Back to Top
pnschofield View Drop Down
Newbie
Newbie
Avatar

Joined: 14-Sep-2007
Location: United States
Posts: 18
Post Options Post Options   Quote pnschofield Quote  Post ReplyReply Direct Link To This Post Posted: 09-Oct-2007 at 10:23am
Originally posted by jeffdoolittle

I tend to think of this in terms of a standard ADO.NET dataset (which, after all, is what a Persistence Manage encapsulates).  In any web application, you're not going to want to have one ADO.NET data set that is shared among all website visitors.  Instead, you're going to instantiate, populate and persist one per user session.


Can you illustrate this a little further what you mean by this?  I can understand storing information that is specific to a user's session in Session state, but I'm not familiar with the model of caching a copy of all types of application data in each user's Session state.  Microsoft seems to have something else in mind.  The ASP.NET Cache API, for example, is indeed designed around the principle of sharing one instance of data among all visitors to increase both performance and scalability.  In most examples provided by Microsoft, you will see DataSets placed in the Cache for sharing data among many users.

Here's my analysis of what is considered the best practice for web applications (feel free to substitute "DataSet" for "cache"):  if I'm storing information on each active user of an application, I might want to have one instance of my User entity in a single shared cache, and query the cache for an instance as necessary. As an alternative, since a User entity is lightweight, it would probably be a candidate for placing in the Session. On the other hand, if I have a catalog of 10,000 products, I would certainly want to store no more than one instance of each of those entities in the cache.  If I had 1,000 users, each with their own copy of the 10,000 product catalog in their Session, then I have increased my memory usage 1,000-fold by storing 999 redundant copies of the data.   As the number of users grows, so does memory utilization, and my web application would soon come grinding to a halt under the weight of all that redundant data.

Granted, you could argue that sharing data increases concurrency issues, and data that the user is in the process of updating would probably best be stored in Session, but it seems to me that everything else is best shared in a shared cache of some sort.


Edited by pnschofield - 09-Oct-2007 at 11:03am
Back to Top
pnschofield View Drop Down
Newbie
Newbie
Avatar

Joined: 14-Sep-2007
Location: United States
Posts: 18
Post Options Post Options   Quote pnschofield Quote  Post ReplyReply Direct Link To This Post Posted: 09-Oct-2007 at 10:38am
If the problem is security in a multi-user environment, then I think one solution would be to extend the PM with the concept of "UserContext" which would allow you to specify a QueryStrategy that attached a specific user to that query.  The results of that query would be stored by the PM in a separate cache specific to that user.  That would solve any security issues involved with users sharing a single PM.

// This query is going to return entities that should only be viewed by pnschofield:
EntityQuery query = new EntityQuery;
query.QueryStrategy.UserContext.User = "pschofield";


Back to Top
davidklitzke View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 14-Jun-2007
Posts: 715
Post Options Post Options   Quote davidklitzke Quote  Post ReplyReply Direct Link To This Post Posted: 09-Oct-2007 at 3:56pm

I think that Jeff has made the essential point here.

 

I tend to think of this in terms of a standard ADO.NET dataset (which, after all, is what a Persistence Manage encapsulates).  In any web application, you're not going to want to have one ADO.NET data set that is shared among all website visitors.  Instead, you're going to instantiate, populate and persist one per user session.

 

I understand your point that "it's considered a best practice to avoid using session state whenever possible", but we also know that a stateless application isn’t as interesting or as fun as one that carries a fair amount of state.

 

There is no requirement that a DevForce Web Application use a lot of memory for its PM Cache.  In fact, I would expect that a DevForce Web App would typically have a much smaller footprint than a comparable desktop smart client application.  If you’re really concerned about the scalability of your Web App, use less or even no caching.

 

One final point,  A PM is not something that you can dispose of as needed under low memory conditions and then rehydrate later when needed.  That is because a Persistence Manager is non-serializable.  For example, A Persistence Manager cannot be persisted to a SQL Server Database and then restored.



Edited by davidklitzke - 09-Oct-2007 at 3:56pm
Back to Top
jeffdoolittle View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Jun-2007
Location: United States
Posts: 146
Post Options Post Options   Quote jeffdoolittle Quote  Post ReplyReply Direct Link To This Post Posted: 09-Oct-2007 at 8:05pm

Originally posted by davidklitzke

a Persistence Manager is non-serializable.  For example, A Persistence Manager cannot be persisted to a SQL Server Database and then restored.

While this is off topic, and probably simply academic, wouldn't it be possible to use SaveEntitySet and persist the stream in an SQL database?  Of course, if you reloaded the entity set, you wouldn't have the original query cache, but otherwise wouldn't you pretty much have a "rehydrated" PM?
Back to Top
pnschofield View Drop Down
Newbie
Newbie
Avatar

Joined: 14-Sep-2007
Location: United States
Posts: 18
Post Options Post Options   Quote pnschofield Quote  Post ReplyReply Direct Link To This Post Posted: 10-Oct-2007 at 1:01pm
David, I accept your point about session data being critical to web applications.  I'm just trying to distinguish user-specific session data from global application data.  It sounds like we're lumping everything that comes from the database into the session bucket when a good deal of it (such as the product catalog in my earlier example), is global application data and should be shared across all user sessions with caching whenever possible.

I'm hoping to see that IdeaBlade recognizes the difference and has a best practice for providing quick, cached access to global application data without creating a duplicate copy for each user.  I would think that global application data is where you would have the best odds of a cache hit, as multiple users have the opportunity to perform queries that have already been performed by other users.

Maybe it would help to think of it in terms of a use case involving Amazon.com customers.  Picture a large number of users visiting Amazon and searching for "Harry Potter".  From what I gather, the IdeaBlade model would have us cache an identical list of Harry Potter books for every single user for as long as their session persists (unless we clear their cache manually).  Every new search by a different user would perform the same query against the database and would store the same redundant data in the new user's session, using more system memory.  The only time we would see a cache hit would be if a user performed the same search twice.  Wouldn't it make more sense to have the results of a catalog search cached in a single shared location?  The first time the search is performed, the results are cached and every subsequent user's results are served from the cache.  Scalability and performance in one fell swoop!

Back to Top
IdeaBlade View Drop Down
Moderator Group
Moderator Group
Avatar

Joined: 30-May-2007
Location: United States
Posts: 353
Post Options Post Options   Quote IdeaBlade Quote  Post ReplyReply Direct Link To This Post Posted: 10-Oct-2007 at 9:35pm
Jeff is correct.  If you do want to persist information from an AspDataSource application, you cannot persist the IdeaBlade Persistence Manager, but you could persist one or more EntitySets using SaveEntitySet.
Back to Top
jeffdoolittle View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Jun-2007
Location: United States
Posts: 146
Post Options Post Options   Quote jeffdoolittle Quote  Post ReplyReply Direct Link To This Post Posted: 10-Oct-2007 at 11:48pm
Paul,
 
I think your best bet is to create an application level PM that contains data available to all users, and a session level pm that contains user specific information.  This would probably be non-trivial to implement, but I don't see any theoretical problems with such a scenario.


Edited by jeffdoolittle - 10-Oct-2007 at 11:49pm
Back to Top
pnschofield View Drop Down
Newbie
Newbie
Avatar

Joined: 14-Sep-2007
Location: United States
Posts: 18
Post Options Post Options   Quote pnschofield Quote  Post ReplyReply Direct Link To This Post Posted: 11-Oct-2007 at 1:03pm
Originally posted by jeffdoolittle

Paul,
 
I think your best bet is to create an application level PM that contains data available to all users, and a session level pm that contains user specific information.  This would probably be non-trivial to implement, but I don't see any theoretical problems with such a scenario.


Sounds like a great solution, thanks for the help with this.

Paul
Back to Top
CetinBasoz View Drop Down
Newbie
Newbie


Joined: 15-Jun-2007
Location: Turkey
Posts: 4
Post Options Post Options   Quote CetinBasoz Quote  Post ReplyReply Direct Link To This Post Posted: 11-Oct-2007 at 3:12pm
Hi Paul,
Thanks for the topic:) I'll be following it. That is also my concern lately.
PS: Overwhelmed by deadlines couldn't do any tests and simply sticked with Session approach.
Back to Top
pnschofield View Drop Down
Newbie
Newbie
Avatar

Joined: 14-Sep-2007
Location: United States
Posts: 18
Post Options Post Options   Quote pnschofield Quote  Post ReplyReply Direct Link To This Post Posted: 12-Oct-2007 at 9:41am
I have a quick follow-up question.  When accessing the shared application PM, should we take care to ensure that only one query is being executed by the PM at one time to avoid any threading issues?

Thanks,
Paul
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down