Adding support for centralized session and formstate management.
Hi all,
Related ticket: http://trac.qcu.be/projects/qcubed/ticket/771
When it comes to web applications, there is one worry each and everyone of us want to have: having the need to install our application on two or more machines because we are getting too many hits and the single server we use is crying for mercy with a sheet showing 99% resource usage. Well, it is indeed a worry because of two things:
1. When you make your application available on more than one machine, you get all machines with different instances of PHP running on them, which means the 'SESSION' varies from one server to another. So if you had a load balancer who sent the 'login' request to the first machine and the next request to another one (and you happen to be using PHP Sessions to manage user login and logout, like many others), your 'user' gets 'logged out' the very next page after his login!
2. QCubed heavily depends on the 'FormState' data for every page it creates. So even if you happen to have some way to keep the user logged in, you will find yourself needing a way to centralize your FormStates.
We will take them one by one. First, the session problem:
Fortunately PHP provides with a nice API set to allow you to use your own ways to treat sessions. So you can use those APIs (basically, session_set_save_handler function does the trick, but it simply registers other session handling functions you need to write). One way to work around with PHP sessions is to mount a network directory and use the path as the session save path on each of the server. Well, what it means indirectly is that you have got a hell lot of bad times coming up: getting a new server for the purpose, setting network connections, setting up all the web servers in use to make sure that all of them are using the same directory as their source for Session data and so on. But that is just the surface. You also need to make sure that the directory you mounted can take up a lot of load coming from the server because Sessions are saved in files and the Disk IO will shoot up (thinking SSDs, huh?).
Well, since you can override the default session handler, why not just make them use a database for saving all the data? Simple and easy and you get rid of a lot of problems associated with other approaches. Well, I think by all means, creating a new table on a database is simpler than getting a new machine, setting it up, configuring network and so on! Plus, the IO part is taken care by the DB (with more buffer allocated to it, things get faster). Utilizing the same idea (with a thanks to the PHP team for putting up the real nice API), I created a class called as 'QSessionHandler' which uses one of your QCubed application databases (the ones mentioned in configuration.inc.php) to create, read, write and destroy sessions. It keeps a lot of things simpler and makes sure that on a fortunate day when you get a lot of traffic, you are not going to find yourself pull hairs but editing a configuration file.
The feature requires you to create a new table in one of the databases in use with three columns (with exact names as below):
1. id => a varchar(32) field
2. last_access_time => an integer field
3. data => a 'text' field.
The feature does not require you to codegen this table. Once done, supply the name of the table and the database index (not the name, but the numerical index of the database in the DB_CONNECTION list) in configuration.inc.php and restart your web server. You are ready to go.
As for formstate centralization on a DB, well, simply turn this feature on and use 'QSessionFormStateHandler' and you are ready to go! I have tried and tested it, and it works :) Please help test this to find if something is wrong.
Regards,
Vaibhav

I'm having a bit of a problem with this feature. I keep losing the session after a few page refreshes. I can tell the session is being created correctly and the data is being updated, but then after a few page refreshes the data just disappears. Any ideas about where to look for the issue?
How big are those pages? And after how many refreshes and page views approximately does that happen?
See, there are two possibilities -
1. Session is expiring. You need to increase that in php.ini or check if something else is making it expire.
2. FormState is expiring. In that case again, since the code manages only the session, you might be making too many requests which swells up the session data and probably the amount of memory PHP can use for a single run is not adequate to accomodate the session size in that case.
Also, please see http://trac.qcu.be/projects/qcubed/ticket/801 . This is a very new feature I have added to manage the formstates separately on the DB itself.
Once again, in case you are getting any error, what is it?
Regards