Author |
Message |
fkelly
Former Moderator in Good Standing

Joined: Aug 30, 2005
Posts: 3312
Location: near Albany NY
|
Posted:
Wed Aug 02, 2006 11:13 am |
|
Disclaimer: don't try this on a production system or without backup, it's just an idea that needs refinement and discussion.
One thing I was always taught in DP (data processing) was "avoid IO". So starting out with PHPnuke and looking at how the code worked I was surprised to see how mainfile "constantly" was reading the config table. This led to discussions of statefulness and statelessness with Montego that taught me a few things but didn't extinquish my desire to take some of the IO out.
One place that you see what I consider excessive IO is where mainfile reads in the configuration variables. This happens every time thru and thus can be dozens or even hundreds of times for a single user session. The code I'm talking about starts out:
Code:define('NUKE_FILE', true);
$dbi = sql_connect($dbhost, $dbuname, $dbpass, $dbname);
$result = $db->sql_query('SELECT * FROM '.$prefix.'_config');
$row = $db->sql_fetchrow($result);
$sitename = $row['sitename']; .....
|
at about line 210 in a current distribution. It might vary in location slightly in yours.
The code goes on to stow away about 45 configuration values from the config table into variables for use within Nuke.
So how could this be avoided. Well I'm now experimenting with using sessions and storing these values into a $_SESSION variable that I'm calling config. This is an associative array that uses the configuration variable name as the key and the value as the value. Here's the code I have so far:
Code:Define('NUKE_FILE', true);
session_start();
if (!isset($_SESSION['config'])) {
$dbi = sql_connect($dbhost, $dbuname, $dbpass, $dbname);
$result = $db->sql_query('SELECT * FROM '.$prefix.'_config');
$row = $db->sql_fetchrow($result);
$contentz .= 'config session variable is set and database read <br>';
$_SESSION['config'] = array (
"sitename" => $row['sitename'],
"nukeurl" => $row['nukeurl'],
"site_logo" => $row['site_logo'],
"slogan" => $row['slogan'],
"startdate" => $row['startdate'],
"adminmail" => stripslashes($row['adminmail']),
"anonpost" =>$row['anonpost'],
"Default_Theme" => $row['Default_Theme'],
"foot1" => $row['foot1'],
"foot2" => $row['foot2'],
"foot3" => $row['foot3'],
"commentlimit" => intval($row['commentlimit']),
"anonymous" => $row['anonymous'],
"minpass" => intval($row['minpass']),
"pollcomm" => intval($row['pollcomm']),
"articlecomm" => intval($row['articlecomm']),
"broadcast_msg" => intval($row['broadcast_msg']),
"my_headlines" => intval($row['my_headlines']),
"top" => intval($row['top']),
"storyhome" => intval($row['storyhome']),
"user_news" => intval($row['user_news']),
"oldnum" => intval($row['oldnum']),
"ultramode" => intval($row['ultramode']),
"banners" => intval($row['banners']),
"backend_title" => $row['backend_title'],
"backend_language" => $row['backend_language'],
"language" => $row['language'],
"locale" => $row['locale'],
"multilingual" => intval($row['multilingual']),
"useflags" => intval($row['useflags']),
"notify" => intval($row['notify']),
"notify_email" => $row['notify_email'],
"notify_subject" => $row['notify_subject'],
"notify_message" => $row['notify_message'],
"notify_from" => $row['notify_from'],
"moderate" => intval($row['moderate']),
"admingraphic" => intval($row['admingraphic']),
"httpref" => intval($row['httpref']),
"httprefmax" => intval($row['httprefmax']),
"CensorMode" => intval($row['CensorMode']),
"CensorReplace" => $row['CensorReplace'],
"copyright" => $row['copyright'],
"Version_Num" => htmlentities(strip_tags($row['Version_Num'])));
foreach ($_SESSION['config'] as $key => $value) {
$contentz .= $key . '='. $value . '<br>';
}
}
foreach ($_SESSION['config'] as $key => $value) {
// $contentz .= $key . '='. $value . '<br>';
$a = $key;
a = $value;
}
|
The $contentz variable is just used to accumulate diagnostic information and will eventually be dispensed with, so ignore it. The intent of this block of code is that if the session variable has been set then we know config values are stored and we don't have to reread the table. For compatibility with the other nuke programs which use existing variable names (e.g., $foot2) we loop thru the session['config'] array and use variable variable features to load the information from the array into individual variables.
I've tested this on my test site and it seems to be working as intended. My diagnostic block (see:
Only registered users can see links on this board! Get registered or login!
echoes out the contents of the session array once per session and after that skips it plus the database read. Yet the individual variables seem to stay populated. If I close down firefox, the session goes away and the database read and echo of variables is done ONCE. Dare I call it statefullness, I think not but it may be worth considering.
Now I'm not sure sessions work the same on all servers or installations so it would help if anyone (after looking at my disclaimer) could give this a try. Also any comments and suggestions are welcome. |
|
|
|
 |
kguske
Site Admin

Joined: Jun 04, 2004
Posts: 6437
|
Posted:
Wed Aug 02, 2006 1:22 pm |
|
There are number of opportunities where caching or storing info in sessions could improve performance, and this is an interesting approach. One concern: what happens when you need to make a change to the configuration, and people have this info stored in sessions? |
_________________ I search, therefore I exist...
Only registered users can see links on this board! Get registered or login! |
|
|
 |
fkelly

|
Posted:
Wed Aug 02, 2006 2:35 pm |
|
I believe that the changed information would not be reflected until they logged out and/or shut down firefox (oops I mean their browser) and came back in. I also believe there's a session expiration time that is settable but I'm not sure about that. Looking at the variables themselves I don't see anything that's absolutely critical to have reflected immediately or anything that normally would be changed very often.
I'm not an expert on sessions by any means and in my reading it appears that they work differently on different release levels of PHP and perhaps with different browsers. So I'm not sure this will work but that's why I'm putting it out there for people to look at.
I was thinking that if we could get this to work reliably we could save the 45 variable assignments every time thru mainfile by just using the $_SESSION variables directly throughout Nuke but that would require a lot of code review and changing and might threaten compatibility with other modules until they are changed. The approach might also work in functions like is_user or is_admin but let's take it one step at a time.
I'm also not sure how we'd measure any performance improvements as I don't know if page generation time is a very reliable indicator. It would be nice to have some kind of benchmark for a set workload on the old and new versions of mainfile. |
|
|
|
 |
kguske

|
Posted:
Wed Aug 02, 2006 3:07 pm |
|
Right. djmaze did a lot of work caching that information (user info, maybe even configuration) and built that into his original cpg-nuke. It significantly reduced table reads and load time. |
|
|
|
 |
montego
Site Admin

Joined: Aug 29, 2004
Posts: 9457
Location: Arizona
|
Posted:
Thu Aug 03, 2006 6:01 am |
|
You will want to test the heck out of this. I don't know what happens when session_start() is called multiple times within ONE "round trip" through a user's key click. NukeSentinel 2.5.0 is now using sessions for flood control and I have had no time to investigate if its being used elsewhere already.
Just worth a look-see and possible additional researching. |
_________________ Only registered users can see links on this board! Get registered or login!
Only registered users can see links on this board! Get registered or login! |
|
|
 |
fkelly

|
Posted:
Thu Aug 03, 2006 7:38 am |
|
Agreed Montego, about the testing. Note this topic is getting implicitly merged with the diagnostic block topic but I'll repeat a bit. I've looked thru the PHP comments area after the documentation for sessions and there are quite a few issues that could come back to bite us. I'm just not seeing them in my testing but I'm only working in one (or maybe two) "environments". At fkelly.org you can see what's happening with the code above, and it appears that session_start() being repeated has no bad effects. If you look at the diagnostic block in the center bottom of the page you will see that the config session variable is only echoed one time "per session" and therefore (I believe) the database is only read once.
As to session_start() the documentation states:
Quote: | The session support allows you to register arbitrary numbers of variables to be preserved across requests. When a visitor accesses your site, PHP will check automatically (if session.auto_start is set to 1) or on your request (explicitly through session_start() or implicitly through session_register()) whether a specific session id has been sent with the request. If this is the case, the prior saved environment is recreated.
|
and my interpretation of that is that session_start() simply gives you access to the variables. |
|
|
|
 |
montego

|
Posted:
Thu Aug 03, 2006 8:34 am |
|
There is a note in the PHP manual which states this:
Quote: |
Note:
As of PHP 4.3.3, calling session_start() while the session has already been started will result in an error of level E_NOTICE. Also, the second session start will simply be ignored.
|
There must be a way, though, to check and see if a session is already active. Maybe check the $_SESSION array for a size greater than 0? Just thinking out loud here... |
|
|
|
 |
fkelly

|
Posted:
Thu Aug 03, 2006 9:39 am |
|
In the user contributed notes of that section of the manual there is this:
Quote: | To avoid the notice commited by PHP since 4.3.3 when you start a session twice, check session_id() first:
if (session_id() == "")
session_start(); |
I thought I could outsmart it by putting my session_start after the test to see if the $_SESSION['config'] was set but that doesn't work. So I added the check of session_id "outside" my if test as per:
Code:define('NUKE_FILE', true);
if (session_id() == "")
session_start();
if (!isset($_SESSION['config'])) {
|
and that seems to work okay. I spent some time reading links from the documentation into articles on sessions and PHP. Conclusion: the way and what I am using them for seems to be exactly what was intended. That is to take some of the statelessness out. However, whether my code needs to be refined further to work reliably in a range of environments remains to be seen. |
|
|
|
 |
montego

|
Posted:
Thu Aug 03, 2006 1:45 pm |
|
Excellent work fkelly!
and
Can't wait for PHP-Portal where we can use sessions the way they were intended... (and ditch PHP-Nuke's antiquated infrastructure).
I would want us to research more on the server resources aspect of stuffing more and more data into them. For some sites, like mine, where I get 1 - 2 hits a day :rotlf:, it doesn't matter, but a site like Raven's.... Just don't know enough about PHP session management / overhead is like. |
|
|
|
 |
fkelly

|
Posted:
Thu Aug 03, 2006 2:18 pm |
|
Thanks Montego. And I can't wait either, but I will
I'm sure Raven knows more about the performance aspects than the rest of us. I just came from looking at the statistics on my production site and they really don't tell you anything that would be useful in performance tuning.
At one point about six months ago I had added a field to the config table and I was incrementing it every time the table was read so I could see how often it was getting hit. I think that I was looking at how much the use of static variables in a few of the mainfile functions was saving in terms of data base access. But that's a pretty crude approach.
I know from when I had a real life that performance tuning can be pretty counter-intuitive and that it's really necessary to have some good benchmarks and be able to measure things to be sure you are really moving in the right direction. I just don't know much about it in this environment. |
|
|
|
 |
montego

|
Posted:
Thu Aug 03, 2006 2:28 pm |
|
Just remember from our discussions long back that mainfile.php is only really parsed and executed only ONCE in PHP-Nuke as I believe include_once and require_once are used everywhere (just did a search and found only one relevant straight "include", but it is insignificant). Yes, functions are called over and over and over again, but they are only parsed once. If there are PHP statements outside of a function, they are only executed at most once.
So, for a given "round-trip cycle" from a user's key click to the page being sent back to the browser, the config table values are only grabbed from the db once. You had even validated that finally in your testing.
HOWEVER, what you are proposing now is eliminating this from happening on EVERY "round-trip" per user. It is an excellent idea and worth considering. |
|
|
|
 |
Canadaka
New Member


Joined: Feb 10, 2006
Posts: 23
|
Posted:
Sat Aug 26, 2006 2:43 am |
|
thoroughly has this been tested? I would love to impliment this on my site, every little bit helps. I have been on a mission to try and reduce the number of queries phpnuke uses on my site and optimize other things.
See my post here:http://www.nukecops.com/postp218075.html |
|
|
|
 |
fkelly

|
Posted:
Sat Aug 26, 2006 8:08 am |
|
It has not been tested that thoroughly at all. I am running it on my Ravennuke test site (the only purpose of this site is to test Ravennuke distributions) at fkelly.org. Feel free to go over there but since the code operates "behind the scenes" you really won't be able to tell anything unless there's a problem. Other than that it has not been tested that I know of. I keep meaning to move it over to my production site and try it on my users (a bicycle club site) but I keep not getting around to it. One concern I have or consideration might be a better word is to find a way to actually measure any query reduction that takes place before and after the change. The statistics that I get from my sites don't really tell me that.
If you do decide to test it I would very much appreciate it if you'd post the results back here. |
|
|
|
 |
|