replace session management routines with memcached

This commit is contained in:
Jeremy Newman
2008-02-08 13:15:54 -06:00
parent 86ced92c4c
commit 7666f6d0da
7 changed files with 115 additions and 162 deletions

View File

@@ -16,12 +16,6 @@ inactiveUserCheck();
/* check to see if there are orphaned versions in the database */ /* check to see if there are orphaned versions in the database */
orphanVersionCheck(); orphanVersionCheck();
/* check and purge any orphaned messages stuck in sessionMessages table */
orphanSessionMessagesCheck();
/* check and purge any expired sessions from the session_list table */
orphanSessionListCheck();
/* report error log entries to admins and flush the error log after doing so */ /* report error log entries to admins and flush the error log after doing so */
reportErrorLogEntries(); reportErrorLogEntries();
@@ -197,65 +191,6 @@ function orphanVersionCheck()
mail_appdb($sEmail, $sSubject, $sMsg); mail_appdb($sEmail, $sSubject, $sMsg);
} }
/* this function checks to see if we have any orphaned session messages */
/* These orphaned messages are an indication that we've put a message into */
/* the system without displaying it and it becomes effectively lost forever */
/* so we'll want to purge them here after reporting how many we have */
function orphanSessionMessagesCheck()
{
global $sEmailSubject;
$iSessionMessageDayLimit = 1; /* the number of days a session message must be stuck before being purges */
/* get a count of the messages older than $iSessionMessageDayLimit */
$sQuery = "SELECT count(*) as cnt from sessionMessages where TO_DAYS(NOW()) - TO_DAYS(time) > ?";
$hResult = query_parameters($sQuery, $iSessionMessageDayLimit);
$oRow = query_fetch_object($hResult);
$iMessages = $oRow->cnt;
$sMsg = "Found ".$iMessages." that have been orphaned in the sessionMessages table for longer than ".$iSessionMessageDayLimit." days\r\n";
$sMsg.= " Purging these messages.\r\n";
$sSubject = $sEmailSubject."Orphaned session messages cleanup\r\n";
$sEmail = User::get_notify_email_address_list(null, null); /* get list admins */
if($sEmail)
mail_appdb($sEmail, $sSubject, $sMsg);
/* purge the messages older than $iSessionMessageDayLimit */
$sQuery = "DELETE from sessionMessages where TO_DAYS(NOW()) - TO_DAYS(time) > ?";
$hResult = query_parameters($sQuery, $iSessionMessageDayLimit);
}
/* this function checks to see if we have any orphaned sessions */
/* sessions need to be expired or the session_list table will grow */
/* by one row each time a user logs */
function orphanSessionListCheck()
{
global $sEmailSubject;
/* get a count of the messages older than $iSessionListDayLimit */
$sQuery = "SELECT count(*) as cnt from session_list where TO_DAYS(NOW()) - TO_DAYS(stamp) > ?";
$hResult = query_parameters($sQuery, SESSION_DAYS_TO_EXPIRE + 2);
$oRow = query_fetch_object($hResult);
$iMessages = $oRow->cnt;
$sMsg = "Found ".$iMessages." sessions that have expired after ".(SESSION_DAYS_TO_EXPIRE + 2)." days\r\n";
$sMsg.= " Purging these sessions.\r\n";
$sSubject = $sEmailSubject."Orphan sessions being expired\r\n";
$sEmail = User::get_notify_email_address_list(null, null); /* get list admins */
if($sEmail)
mail_appdb($sEmail, $sSubject, $sMsg);
/* purge the messages older than $iSessionMessageDayLimit */
$sQuery = "DELETE from session_list where TO_DAYS(NOW()) - TO_DAYS(stamp) > ?";
$hResult = query_parameters($sQuery, SESSION_DAYS_TO_EXPIRE + 2);
}
// report the database error log entries to the mailing list // report the database error log entries to the mailing list
function reportErrorLogEntries() function reportErrorLogEntries()
{ {

View File

@@ -252,22 +252,13 @@ function pHttpDate($sDate) {
*/ */
function addmsg($shText, $color = "black") function addmsg($shText, $color = "black")
{ {
if($color) $GLOBALS['session']->addmsg($shText, $color);
$shText = "<font color='$color'> $shText </font>\n";
$sQuery = "INSERT INTO sessionMessages VALUES (null, ?, '?', '?')";
if (!query_parameters($sQuery, "NOW()", session_id(), $shText))
{
echo "An error has occurred in addmsg()";
echo $shText;
}
} }
function purgeSessionMessages() function purgeSessionMessages()
{ {
$sQuery = "truncate sessionMessages"; $GLOBALS['session']->purgemsg();
query_parameters($sQuery);
} }
@@ -276,19 +267,17 @@ function purgeSessionMessages()
*/ */
function dumpmsgbuffer() function dumpmsgbuffer()
{ {
$hResult = query_parameters("SELECT * FROM sessionMessages WHERE sessionId = '?'", session_id()); $GLOBALS['session']->dumpmsgbuffer();
if(!$hResult)
return;
while($oRow = query_fetch_object($hResult)) echo html_frame_start("","300","",5);
foreach ($GLOBALS['session']->msg as $msg)
{ {
echo html_frame_start("","300","",5); if ($msg['color'] == "red")
echo "<div align=center> $oRow->message </div>"; $msg['color'] = "{$msg['color']};text-decoration:blink";
echo html_frame_end("&nbsp;"); echo "<div align=\"center\" style=\"font-color:{$msg['color']};\"> {$msg['msg']} </div>";
echo "<br>\n";
} }
echo html_frame_end("&nbsp;");
query_parameters("DELETE FROM sessionMessages WHERE sessionId = '?'", session_id()); echo "<br>\n";
} }
/** /**

View File

@@ -2,25 +2,36 @@
/* /*
* session.php - session handler functions * session.php - session handler functions
* sessions are stored in a database table * sessions are stored in memcached
* http://www.danga.com/memcached/
*/ */
/* the number of days a session cookie is flaged to last */
define("SESSION_DAYS_TO_EXPIRE", 2);
class session class session
{ {
// defines
var $_server;
var $_expire;
var $_db;
var $name;
var $msg;
// create session object // create session object
function session ($name) function session ($name, $server = "127.0.0.1", $expire = 2)
{ {
// set the connection server
$this->_server = $server;
// set the session and cookie expiration time in days (default 30 days)
$this->_expire = (60 * 60 * 24 * $expire);
// set name for this session // set name for this session
$this->name = $name; $this->name = $name;
// define options for sessions // define options for sessions
ini_set('session.name', $this->name); ini_set('session.name', $this->name);
ini_set('session.use_cookies', true); ini_set('session.use_cookies', true);
ini_set('session.use_only_cookies', true); ini_set('session.use_only_cookies', true);
// setup session object // setup session object
session_set_save_handler( session_set_save_handler(
array(&$this, "_open"), array(&$this, "_open"),
@@ -31,14 +42,20 @@ class session
array(&$this, "_gc") array(&$this, "_gc")
); );
// default lifetime on session cookie (SESSION_DAYS_TO_EXPIRE days) // default lifetime on session cookie
session_set_cookie_params( session_set_cookie_params(
(60*60*24*SESSION_DAYS_TO_EXPIRE), $this->_expire,
'/' '/'
); );
// start the loaded session // start the loaded session
session_start(); session_start();
// make sure we have a valid memcache server connection
if (!$this->_db->getVersion())
{
trigger_error("Unable to Connect to Session Server", E_USER_ERROR);
}
} }
// register variables into session (dynamic load and save of vars) // register variables into session (dynamic load and save of vars)
@@ -57,52 +74,91 @@ class session
// destroy session // destroy session
function destroy () function destroy ()
{ {
if(session_id() != "") session_destroy();
session_destroy();
} }
// open session file (not needed for DB access)
function _open ($save_path, $session_name) { return true; }
// close session file (not needed for DB access) // add alert message to buffer that will be displayed on the Next page view of the same user in html class
function _close () { return true; } function addmsg ($text, $color = "black")
// read session
function _read ($key)
{ {
$result = query_parameters("SELECT data FROM session_list WHERE session_id = '?'", $key); if (!isset($_SESSION['_msg']))
if (!$result) { return null; } $_SESSION['_msg'] = array();
$oRow = query_fetch_object($result); $_SESSION['_msg'][] = array(
if($oRow) 'msg' => $text,
return $oRow->data; 'color' => $color
);
}
// add alert message that will be displayed on the current page output in html class
function alert ($text, $color = "black")
{
$this->msg[] = array(
'msg' => $text,
'color' => $color
);
}
// clear session messages
function purgemsg ()
{
$this->msg[] = array();
$_SESSION['_msg'][] = array();
}
// output msg_buffer and clear it.
function dumpmsgbuffer ()
{
if (isset($_SESSION['_msg']) and is_array($_SESSION['_msg']))
{
foreach ($_SESSION['_msg'] as $alert)
{
$this->msg[] = $alert;
}
}
$_SESSION['_msg'] = array();
}
// connect to session
function _open ($save_path, $session_name)
{
$this->_db = new Memcache;
return $this->_db->connect($this->_server, "11211");
}
// close the session
function _close ()
{
return $this->_db->close();
}
// restore a session from memory
function _read ($id)
{
return $this->_db->get($id);
}
// write the session
function _write ($id, $data)
{
if ($this->_db->get($id))
{
$this->_db->replace($id, $data, null, $this->_expire);
}
else else
return NULL; {
$this->_db->set($id, $data, null, $this->_expire);
}
return true;
} }
// write session to DB
function _write ($key, $value)
{
$messages = "";
if(isset($GLOBALS['msg_buffer']))
$messages = implode("|", $GLOBALS['msg_buffer']);
query_parameters("REPLACE session_list VALUES ('?', '?', '?', '?', '?', ?)", // Delete the Session
$key, $_SESSION['current']->iUserId, get_remote(), $value, $messages, "NOW()"); function _destroy ($id)
return true;
}
// delete current session
function _destroy ($key)
{ {
query_parameters("DELETE FROM session_list WHERE session_id = '?'", $key); return $this->_db->delete($id);
return true;
} }
// clear old sessions (moved into a separate cron process) // Garbage Collector (Not Needed for MemCache)
function _gc ($maxlifetime) function _gc ($maxlifetime)
{ {
query_parameters("DELETE FROM session_list WHERE to_days(now()) - to_days(stamp) >= '?'",
SESSION_DAYS_TO_EXPIRE);
return true; return true;
} }

View File

@@ -13,7 +13,6 @@ drop table if exists appData;
drop table if exists appBundle; drop table if exists appBundle;
drop table if exists appVotes; drop table if exists appVotes;
drop table if exists appNotes; drop table if exists appNotes;
drop table if exists sessionMessages;
/* /*
@@ -176,15 +175,3 @@ create table appNotes (
key(noteId) key(noteId)
); );
/*
*
*/
create table sessionMessages (
id int not null auto_increment,
time datetime,
sessionId varchar(32),
message text,
key(id),
index(sessionId)
);

View File

@@ -5,12 +5,12 @@ echo NOTE: It is ok for this to fail if the user already exists
echo there does not appear to be a way to create a user only echo there does not appear to be a way to create a user only
echo if they do not exist so we have to live with a potential echo if they do not exist so we have to live with a potential
echo error after we try. echo error after we try.
mysql -p -u root < create_user.sql mysql -p -u root apidb < create_user.sql
echo Create the apidb database, and tables echo Create the apidb database, and tables
cat create_apidb_base.sql appdb_tables.sql \ cat create_apidb_base.sql appdb_tables.sql \
prefs_list.sql user_list.sql user_prefs.sql \ prefs_list.sql user_list.sql user_prefs.sql \
user_privs.sql session_list.sql app_category.sql \ user_privs.sql app_category.sql \
maintainers.sql buglinks.sql monitors.sql \ maintainers.sql buglinks.sql monitors.sql \
error_log.sql distributions.sql testResults.sql \ error_log.sql distributions.sql testResults.sql \
| mysql -p -u root | mysql -p -u root apidb

View File

@@ -1,13 +0,0 @@
use apidb;
DROP TABLE IF EXISTS session_list;
CREATE TABLE session_list (
session_id varchar(64) NOT NULL default '',
userid int(11) default NULL,
ip varchar(64) default NULL,
data text,
messages text,
stamp datetime NOT NULL,
PRIMARY KEY (session_id)
) TYPE=MyISAM;

View File

@@ -104,7 +104,6 @@ class table_counts
'testResults', 'testResults',
'user_list', 'user_list',
'user_privs', 'user_privs',
'sessionMessages',
'vendor'); 'vendor');
$this->update_counts(); $this->update_counts();