SiteSetting class need redesign

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

Please do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.

This forum is for discussing mojoPortal development

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

You can monitor commits to the repository from this page. We also recommend developers to subscribe to email notifications in the developer forum as occasionally important things are announced.

Before posting questions here you might want to review the developer documentation.

Do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.
This thread is closed to new posts. You must sign in to post in the forums.
8/30/2006 4:54:13 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

Sounds about right to me.  We should probably also provide a way for modules to indicate cache expiration time.  The expiration time for the page should be computed as the earliest expiration time of any module on the page.  As an example consider a blog module which displays a calendar.  Strictly speaking, a page containing that module should not be cached past midnight.

On a related note, you might want to look into techniques to reduce the overall size of pages.  The mojoportal.com homepage currently weighs in at about 100Kbytes (not counting external files like images, styles, etc).  Since your earlier benchmarks seem to imply that about 80% of time is spent just sending bytes to the browser, anything we could do to reduce page sizes could have a large impact on performance.  For comparison if I convert the HTML to plain text, the resulting size is only 18Kbytes.  So, roughly speaking,  we are sending 100Kbytes of HTML to display 18Kbytes of text.  Looking at the HTML source the 2 things that jumped out at me were 1) ViewState accounts for about 7700 bytes, and 2) the HTML for the calendar accounts for over 15KBytes.  The calendar size could be reduced alot by eliminating the inline styles.  Inline styles are taking up a lot of space elsewhere on the page too.  It wouldn't suprise me if you could get a 20% performance increase just by trimming some of these kinds of fat.



8/30/2006 5:13:29 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

Excellent idea on trying to trim the fat on the page size! The calendar is one of the few controls using the theme.skin file style properties and I think this is what makes inline styles where instead of specifiying things like border fonts and colors in the theme.skin, if we only use the skin to set css classes then it won't render so much inline style. Imagine how big the page was before we started using the CSS adapter for the menu it was rendering as a mess of nested tables with inline styles.

I'm thinking the SiteSettings class could store some key in the cache for each module and we can use a file dependency for each module with a callback method in siteSettings so after an update we touch the file and that raises the callback in siteSettings which can then re-load the module.

I still worry about that initial load thing. Sites that don't get much traffic are the worst affected by that because a higher percent of visitors see the first request which is slow under normal conditions due to the jitting but then this loading of the dictionary on a large site could make that request seem pretty slow. I've seen his before with other .NET sites, once I wrote a windows service called SitePoker that would request a page from sites listed in an xml file site every 15 minutes just to keep them alive, you know just give it a poke every few minutes ;-)
8/30/2006 5:32:09 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

The "after an update we touch the file and that raises the callback" scheme is good but it won't address content that just goes stale at some point in time even if there is no update (e.g. the day that is highlighted on the blog calendar).  Also, touching a file would work fine in a single server environment but might not work in a web farm.  There are a couple ways to address that, but I thought it was worth mentioning...

Initial load is definitely a concern.  Couldn't you load the necessary information on demand instead of loading it all in response to the first request?  I think I'm basically just suggesting that you cache the business objects...

8/30/2006 5:49:04 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

Hmm, I hadn't thought about the web farm issue with file dependencies, I'd be interested in your suggestion for a web farm friendly approach.

I agree about the timing of the calendar I guess it just matters how long we cache the page in outpute cache. if we cache it for up to 5 minutes or so its probably trivial but if we're talking aching for hours then yeah we need to figure out something for midnight expiration.

Good idea loading on demand, we could just load modules a page at a time as pages are requested that would help a lot with the initial load issue. So we don' populate the whole site dictionary upfront, we add to it as needed, this also address my concern about how big the siteSettings obejct could get to some extent.

I saved the home page of this site a few minutes ago and it was 120kb. i was able to trim 20kb just by taking a few things out of the theme.skin file.

I'm about to crash but I'll work on this some more tomorrow night.
8/31/2006 4:55:53 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

I setup my remote server for testing tonight, its on my local network
PIII 800Mhz 1GB RAM
Win2003 Server running IIS and MS SQL 2005

I used a hostname to create my test using http://loadtest/mojo and for a baseline I pointed it first at my local machine, laptop specs mentioned in previous post, identical db on both machines
While running the tests all on the same machine the processor was pegged with aspnet using 50-60% cpu on avg
While running the tests agains the remote machine, the ACT machine had about 80% system idle and the remote machine was pegged at 100%cpu with w3p using 80% on avg

Apparently the hardware is sufficiently better on the local machine that results were much better there

Everything on local machine




hitting the remote PIII 800 machine




I still think the remote machine is probably better for testing but it just goes to show we really can't get absolute numbers as its very hardware dependent. The main thing is to get a baseline and keep tabs on how performance changes as changes to the code are made and as new features are added over time.

I haven't yet started work on the new fangled siteSettings experiment or the page size reduction campaign. Probably this weekend, but at least I'm setup for easy testing.
8/31/2006 5:00:24 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

For web farms, I suggest story the last modified time (for each site, page, and/or module) in the DB.  GetVaryByCustomString() should return a value that includes the relevant last modified time(s) retrieved from the DB.  That means doing a DB call for each request, but I don't think that will be a big performance hit.  If it is, using a temp table might help.

The issue with the calendar was just an example.  The larger point is that a module's output might change due to circumstances other than user action.  Assuming you want to allow add-on modules to support caching, I think we need a more general approach.  At the moment, I'm thinking that SiteModuleControl should have an additional method called GetVaryByCustomString().  Global.GetVaryByCustomString() would instantiate and configure the SiteModuleControls associated with the requested page and would then call each SiteModuleControl's GetVaryByCustomString() method, appending the results.  To handle the blog calendar case, BlogModule.GetVaryByCustomString() would return a string that contained, among other things, the current date.  That would force a new page to be rendered each day.

Make sense?
8/31/2006 5:23:52 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

<
For web farms, I suggest story the last modified time (for each site, page, and/or module) in the DB. 
GetVaryByCustomString() should return a value that includes the relevant last modified time(s) retrieved from the DB. 
That means doing a DB call for each request, but I don't think that will be a big performance hit. 
If it is, using a temp table might help.
<

Something like this does seem to be the only solution to web farm.

<
The issue with the calendar was just an example.  The larger point is that a module's output might change due to
circumstances other than user action.  Assuming you want to allow add-on modules to support caching, I think we need
a more general approach. 
<

I understand, what other circumstances are you thinking of? How long do you think we should cache things?


>
At the moment, I'm thinking that SiteModuleControl should have an additional method
called GetVaryByCustomString().

Global.GetVaryByCustomString() would instantiate and configure the SiteModuleControls associated with the requested page
and would then call each SiteModuleControl's GetVaryByCustomString() method, appending the results. 
<
SiteModuleControl is a web UserControl.
Unless you really mean Module.cs business class which will be managed inside SiteSettings, this seems just as expensive as not caching, if we have to do that I think we should skip the page output cache and just stick with the module cache where we can currently specify different cache times per module.

<
To handle the blog calendar case, BlogModule.GetVaryByCustomString() would return a string that contained, among other things, the current date.  That would force a new page to be rendered each day.
<

Definitely the date can be part of the variance. We also must vary by culture.
8/31/2006 5:36:33 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

I think we can add the last update to the Module class and let SiteSettings orchestrate everything. SiteSettings will cache the last update time of each module for at least 1 minute (thats a lot of requests if under heavy load)

There is some confusion in our terms and I know I'm guilty of using them interchangably. SiteModuleControl inherits from UserControl and is the base class for the .ascx file associated with each feature. Module.cs is the buisiness class it knows which .ascx control is needed, the roles, etc, but there is also a business class associated with each feature Blog.cs, HtmlContent.cs and these are loaded inside the SiteModuleControl and get the actual content from the db.

Currently we have caching at the SiteModule rendered content level with configurable cache time.
8/31/2006 6:52:18 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

what other circumstances [that might change a module's output] are you thinking of?

I can think of several other types of modules whose output would change even without a DB update.  Consider an RSS aggregator, a stock ticker, a quote of the day, weather forecast, or more generally a front-end to some sort of web service.

How long do you think we should cache things?

Assuming we can limit total cache memory usage via the web.config, I think we should cache things until we know they will be invalid.  But force the browser to revalidate so that the user always sees the latest version.

SiteModuleControl is a web UserControl.
Unless you really mean Module.cs business class which will be managed inside SiteSettings,

I meant SiteModuleControl not Module.cs.  I originally thought that you could put all the output caching logic in the business objects, but then I realized that if you want developers to be able to add their own modules, you can't assume that such modules will generate the same HTML for a given set of business objects.  A very common case would be a module that generates different HTML depending on the User-Agent header.  You could also have a module that displays the user's IP address, or more likely, uses it to determine the user's physical location so that content can be better targeted at them.

The bottom line is that if you are caching the output of a SiteModuleControl, the SiteModuleControl needs to have some control over that caching.  Output caching is intrinsically a presentation layer activity, so the logic controlling it belongs in that layer.

this seems just as expensive as not caching,

I suspect not because I think the bulk of the CPU is spent rendering and sending the page to the browser, not instantiating and configuring the SiteModuleControl objects.  One easy way to test this hypothesis would be to measure the performance impact of duplicating the "foreach (Module module in siteSettings.ActivePage.Modules)" loop in Default.aspx.cs (removing the added controls after the first loop completes).

if we have to do that I think we should skip the page output cache and just stick with the module cache where we can currently specify different cache times per module.

For the record, I have no problem skipping output caching.  In fact, I think you should rerun your tests of the benefits of module caching with a more simultaneous browser connections.  You might find that even module caching doesn't buy as much as we thought.  I suspect that the 2 performance bottlenecks are DB I/O and the CPU cycles required to send a rendered page to the browser.  DB I/O might actually not be that big of an issue since the DB isn't that large and doesn't see many writes.  That would mean that the primary way to improve performance would be to reduce the number of bytes sent to the browser.  There are only 2 ways to do that.  The first is to trim the fat in the HTML.  The second is to cache on the browser (or someplace other than the server).
9/1/2006 12:53:37 PM
Gravatar
Total Posts 18439

Re: SiteSetting class need redesign

Yeah I'm kind of back to punting on the page output caching myself. I may take a stab at it later but I'm going to focus on trying to reduce page size as much as possible as you suggest.

How many browser sessions do you recommend using? My last tests above were with 4 browsers. How many should a I ramp it up to? When testing with Act on my laptop against the remote web server, the laptop wasn't working very hard. Is that what I should go by? Ramp it up until the Act machine is working at full capacity?

What I'd like to do is setup a dotnetnuke site, maybe community server site too and try creating comparable tests for each so that I can get an idea of how well we are performing compared to these more popular/well known products.
9/1/2006 2:34:21 PM
Gravatar
Total Posts 148

Re: SiteSetting class need redesign

Repeatedly double num browser sessions up until server cpu pegs at 100% or "average time until first byte" roughly doubles.  That should indicate that the server has hit a bottleneck.  Make sense?
You must sign in to post in the forums. This thread is closed to new posts.