KalikoCMS / KalikoCMS.Core

Open source content management system (CMS) for the ASP.NET platform.
GNU Lesser General Public License v3.0
145 stars 64 forks source link

Running KalikoCMS with Session State = "state server" #95

Open BerndHanisch opened 8 years ago

BerndHanisch commented 8 years ago

Hi,

i noticed wired thing by running KalikoCMS with "state server" as session state configuration. Beside a app pool with more then one worker processes the system gets crazy.

Please test your code with this configuration. at the moment i created an special app directory "CMSAdmin" with a special app pool (1 worker and in process session state). but this isnt a good solution, coz i have to update the files twice; maybe more problems are resulted by this config.

Greetings Bernd

fschultz commented 8 years ago

Interesting, it sounds like the in-memory page tree isn't shared as it should between processes. I was under the impression that worker processes shared the same app domain and with that the same static data, but it seems not in some scenarios.

I will be looking into this, testing with a demo project set up in the same way. Thank you very much for reporting the problem!

fschultz commented 8 years ago

Running a project under the same type of configuration I noticed that I was completely under the wrong impression, each worker process does have its own app domain and thus not sharing static data, in this case the page tree. Only the working process that did the change has the correct page tree.

I have a generally good idea on how to fix this and will be creating a new development branch out of the 1.2.0-branch to create a version that will work in a web garden scenario with multiple worker processes.

BerndHanisch commented 8 years ago

Hi Fredrik,

cool. Sounds good. I´m excited about the flexibility of your code and looking forward for the next update

Thx.

Greetings Bernd

(removed email content /Fredrik)

fschultz commented 8 years ago

Do you use any distributed cache provider in particular? I noticed that the default implementation (using the standard ASP.NET cache) also will be a problem in a multi worker process environment since it will create a separate cache for each worker process and I need to implement an out-of-process cache provider in order to also solve the caching that goes on in the CMS. So if you already use any such provider I can prioritize making an implementation against it.

BerndHanisch commented 8 years ago

Hi Fredrik,

at the moment i use selfmade data caching by using session variables and the standard website caching of MVC5.

Mit freundlichen Grüßen

Bernd Hanisch

EdSF commented 8 years ago

Very interesting! Is this (really) an application issue or perhaps an application setup matter? It would probably be good to determine that before making code changes.

It seems that this setup essentially creates a web garden (web garden mode). See this SO Q&A - its a bit dated and the accepted answer's link is wrong, but the discussion/answers should be helpful.

I haven't done this type of configuration so I think this is a great question - and what answer/setup resolves it - because it seems to be more of a general platform/configuration matter - for all types of ASP.Net applications with the same config (mulitple worker process), not necessarily a Kaliko "issue".

Additional references:

Both Session and Cache are contained within the memory space of a single ASP.NET worker process. But in a Web farm or Web garden, multiple ASP.NET worker processes work together simultaneously. The Session or Cache within any individual ASP.NET worker process cannot manage state across multiple processes.

Therefore, an additional layer is required for state management: an out-of-process Session State server that stores and retrieves state information for every ASP.NET worker process in the Web farm or Web garden.

fschultz commented 8 years ago

Good input and question! It's always important to consider issues before making code changes that affect core functionality. I tend to keep any changes separate from the main project and tread very carefully making changes that even touches the main infrastructure.

The isolation of processes makes Web Gardens very similar to Web Farms although they are running on a single machine, which will result in quite a lot of issues/considerations in any ASP.NET application (such as static variables and InProc cache providers not sharing between processes amongst others). I can't recall on top of my mind any project that I've worked with that have used multiple worker processes, so I'm a bit new to the issues this creates.

For a normal website using Kaliko CMS a single worker process should be quite enough since the routing and infrastructure have been highly optimized for speed and cache mechanisms prevents round-trips to the database. I can see the use of multi-process scenarios if the CMS is added to be a part of another web application that in turn requires more processes when handling requests.

BerndHanisch commented 8 years ago

I use multi worker processes with state server because a lot of database commands of my application needs around 1 second to be complete. The easiest way was to increase worker processes and using state server.

Is it possible to disable caching for the KalikoCMS modules? The CMS part in my application is only a small part. The performance impact should not be so great.

fschultz commented 8 years ago

There's two kinds of caching in the system; one page tree that is used for routing and lookup and one property cache that store data for pages to reduce database lookups. It's quite easy to disable the latter since all that is needed is to implement a version of ICacheProvider that doesn't do anything. But it could also be switched toward an out-of-process cache provider (which I think is the way to go). This can be done without touching the core system.

The page tree part is more difficult to bypass due to the shear amount of work it does (routing, traversing etc.). Without major rewrites it would result in a bit of hammering against the database for each request. A better way forward would be to - through a flag in configuration - to use the cache instead of the statics used today. This should not affect standard installation but only installations that requires out-of-process support.

I hope to be able to start looking at this a bit more the upcoming week.