Welcome to Geeklog, Anonymous Thursday, March 28 2024 @ 12:53 pm EDT

Geeklog Forums

Weather to cache or not


Status: offline

jlhughes

Forum User
Full Member
Registered: 04/25/02
Posts: 154
Why does the PHP weather block cache results? I installed the PHPweather block. With cache turned on, the weather was not updating until you called weather_details. With cache instructions removed, everything appears to work fine and the information is up to date. Is there a downside to running without the cache in the PHP weather block?
 Quote

Status: offline

squatty

Forum User
Full Member
Registered: 01/21/02
Posts: 269
Yes and no...

The down side to not caching is slower performance. There is a lot of overhead associated with connecting to MSNBC for every page request...especially on the front view of your Geeklog site. The hit is not as bad on the details page because the page is not requested as often. Bottom line, the caching is in place to make the performance of your site better! This of course comes with the possibility of users seeing “stale content”

Here's how the caching works:

1) Create a cache file per each registered user - My caching mechanism creates a cache file per each user and more importantly per each users content preference. This guarantees that every user will ONLY see his/her content preferences. If you look in the /path/to/Geeklog/public_html/blockname/cache/ directory, you will see multiple *.cache file names. There is a cache file per each user id.

The code for the registered user cache is listed below. This sample is taken from my news block (display_news.php):

if (($_USER['uid'] > 0)) {

$cache_file = $_CONF['path_html'] . '/news/cache/news-uid' . $_USER['uid'] .'.cache';
$time = split(" ", microtime());
srand((double)microtime()*1000000);
$cache_time_rnd = 100000 - rand(0, 600);

if ( (!(file_exists($cache_file))) ||
((filectime($cache_file) + $cache_time - $time[1]) + $cache_time_rnd (!(filesize($cache_file))) ) {
$fpwrite = fopen($cache_file, 'w');
if(!$fpwrite) {
echo "The system fail to write files. Please check your cache/ directory CHMOD";
return;
}
$boxtitle = get_from_msnbc($location, $code);
fputs($fpwrite, "$boxtitle");
fclose($fpwrite);
} else {
if (file_exists($cache_file)) {
$wfread = fopen($cache_file, 'r');
$boxtitle .= fread($wfread,filesize($cache_file));
fclose($wfread);
}
}
}

Note: You can decrease or increase or decrease the “life” of the cach by changing the value in this line $cache_time_rnd = 100000 - rand(0, 600). Set the $cach_time_rnd = 100 or 300….ect.

2) Create a global cache for anonymous users - This reduces the overhead associated with loading the home page. In addition, it prevents anonymous users from flushing the cache of registered users.

The code for the anonymous user cache is listed below. This sample is taken from my news block (display_news.php):

if (!($_USER['uid'] > 1)) {


$cache_file = $_CONF['path_html'] . '/news /cache/news.cache';
$time = split(" ", microtime());
srand((double)microtime()*1000000);
$cache_time_rnd = 100000 - rand(0, 600);

if ( (!(file_exists($cache_file))) ||
((filectime($cache_file) + $cache_time - $time[1]) + $cache_time_rnd (!(filesize($cache_file))) ) {
$fpwrite = fopen($cache_file, 'w');
if(!$fpwrite) {
echo "The system fail to write files. Please check your cache/ directory CHMOD";
return;
}
$boxtitle = get_from_msnbc($location, $code);
fputs($fpwrite, "$boxtitle");
fclose($fpwrite);
} else {
if (file_exists($cache_file)) {
$wfread = fopen($cache_file, 'r');
$boxtitle .= fread($wfread,filesize($cache_file));
fclose($wfread);
}
}
}

Note: You can decrease or increase or decrease the “life” of the cach by changing the value in this line $cache_time_rnd = 100000 - rand(0, 600). Set the $cach_time_rnd = 100 or 300….ect.

3) Create crons to purge old cache - This is a recent addition, and is NOT detailed in the PHP block downloads. I recently came to the conclusion that on my site (squatty.com) I need to set extremely HIGH caching timeouts in the random seed. This results in a tremendously stellar cache hit ration (about 90%)! The obvious problem with this approach is that content becomes stale. The fix for stale content is to purge cache at regular intervals. For example, I run a cron every 20 minutes to purge all stock cache files. This way I can get updated quotes every 20 minutes. For more information on my crons click here.

4) Delete and re-create user cache on updates - I recently added logic to all the admin.php pages to delete the cache on updates/deletes of content personalization. The cache is re-created upon the next request of the bock.

For example, when a user changes his/her news feed, I run the following:

// Delete users existing cache file
$news_cache = 'news-uid'. $_USER['uid'] .'.cache';
$command = "rm /path/to/geeklog/public_html/news/cache/$news_cache";
exec($command);


In a world without walls and fences, who needs Windows and Gates?
 Quote

Status: offline

jlhughes

Forum User
Full Member
Registered: 04/25/02
Posts: 154
OK, I agree that caching is a good idea for the weather php block (and perhaps other blocks), but I think using mysql makes more sense than creating a cache directory and reading and writing files.

I've added two columns to gl_userprefs. weather_cache holds the weather cache html and weather_cache_age holds the creation timestamp.

When a registered user enters the site, the $_USER global will include both of these new columns. It is a simple process to check the PHP function time() against the value stored in the weather_cache_age column. If the difference is less than the desired interval in seconds, display the stored html. If not, go to MSNBC and get new information and store that in the database.

For anonymous users, the weather_cache and weather_cache_age values are stored with UID 1. If $_USER['uid'] has no value, then uid 1 is queried to get the last cached weather.

I've even added a bit of code that says "Last updated X minutes ago" so people can tell how fresh the weather data is.

You can see an example of this at jomari.com. All of the changes are included in display_weather.php in the function getweather. You can view the contents of that file by clicking here.

 Quote

Anonymous

Anonymous
Nicely done! I never considered using the DB to cache. This approach also integrates the block deeper into Geeklog. I've applied your changes to my site, and will soon make the updates across all my blocks. Thanks!
 Quote

erZwo

Anonymous
Hi!

Could you please proove your Code by copy&paste
from your website? I tried so and and now only the
Last updated function will be displayed.

the HTML-output is broken because all i find in the
weathercache is <table width="100%" border="0" c

bye, Miklas

 Quote

Status: offline

jlhughes

Forum User
Full Member
Registered: 04/25/02
Posts: 154
The source code for display_weather.php is available here, which was in my original post.

I did not mention in my original post that the weather_cache field in the gl_userprefs table needs to be a TEXT field. The weather_cache_age field in gl_userprefs should be INT(11) UNSIGNED

If you created the weather_cache as a VARCHAR field you might have problems like you describe. It would be caused by unescaped single or double quotes in the HTML.

 Quote

erZwo

Anonymous
OK ... That works!
 Quote

All times are EDT. The time is now 12:53 pm.

  • Normal Topic
  • Sticky Topic
  • Locked Topic
  • New Post
  • Sticky Topic W/ New Post
  • Locked Topic W/ New Post
  •  View Anonymous Posts
  •  Able to post
  •  Filtered HTML Allowed
  •  Censored Content