[nycphp-talk] aggregate views on serialized session data WAS: session size important?
Dan Cech
dcech at phpwerx.net
Fri Apr 22 15:22:41 EDT 2005
Mitch Pirtle wrote:
> On 4/22/05, csnyder <chsnyder at gmail.com> wrote:
>>Oh, and, pay special attention to your garbage collection routines - a
>>session table with 800,000 stale records is not a pretty sight.
>
> I never did get ADOdb's session_expiration stuff working to clean out
> those records, and was forced to find another solution. I ended up
> omitting reference to that altogether for an article on using ADOdb
> and got in the John Lim Doghouse for it too (gasp!)
Yeah, never having actually used ADOdb's session handlers in the real
world (because I had my own already) I wasn't aware of this. The gc
handler does seem unnecessarily complex. I'm also not a fan of
pre-computing expiry times, I prefer to set an activity time and compute
the expiry time as needed to keep things consistent if you change the
timeout value.
Here is the handler I used, which assumes you set a column called
'active' to the current gmtime() each time you update the session data
(The optimize table stuff is obviously MySQL specific).
<?php
define('SESSION_TABLE','sessions');
/*! function
internal session management function
!*/
function _sess_gc ($gc_maxlifetime = NULL)
{
$db = ''; //db connection
if (!isset($gc_maxlifetime)) {
$gc_maxlifetime = ini_get('session.gc_maxlifetime');
}
$gc_sql = 'DELETE FROM '. SESSION_TABLE .' WHERE active < '. (gmtime
() - $gc_maxlifetime);
$result = $db->Execute($gc_sql);
if (!is_object($result)) {
trigger_error ('_sess_gc (): Failed to DELETE old sessions.',
E_USER_WARNING);
return FALSE;
}
$opt_sql = 'OPTIMIZE TABLE '. SESSION_TABLE;
$result = $db->Execute($opt_sql);
if (!is_object($result)) {
trigger_error ('_sess_gc (): Failed to OPTIMIZE session table.',
E_USER_WARNING);
return FALSE;
}
/*
// uncomment to test if garbage collection gets called properly
if ($fp = fopen ('/tmp/gc.txt','ab')) {
fwrite($fp,gmtime() .' - '. $gc_sql ."\n");
fclose($fp);
}
*/
// trigger_error ('_sess_gc (): Session Garbage Collection
successful.', E_USER_NOTICE);
return TRUE;
}
> So, I've taken two different approaches to get the "There are X people
> online" view:
>
> 1) store the online status as a boolean in the session table, and just
> get counts
> 2) store the summary count data in memory, and update for each login/logout
>
> I am unconvinced that one is better over the other, what does everyone
> else think? #2 is certainly the fastest until you need multiple
> servers, but #1 means you gotta count for every aggregate.
As for counting users, in MySQL at least, if you put an index on the
'active' field then you can use something like:
'SELECT COUNT(*) FROM '. SESSION_TABLE .' WHERE active >= '. (gmtime()-300);
To get a count of all users active in the last 5 minutes, and (again at
least for MySQL) it should be fairly fast because it can be computed
using only the index.
You could maybe use a hybrid approach where you maintain a value (either
in the db or in some other cache) of the current count and increment it
on login/logoff, but add a function to the session gc handler to perform
the count and keep it in sync. I guess it really depends on how
accurate you want the count to be.
Dan
More information about the talk
mailing list