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 */
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 */
reportErrorLogEntries();
@@ -197,65 +191,6 @@ function orphanVersionCheck()
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
function reportErrorLogEntries()
{

View File

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

View File

@@ -2,17 +2,28 @@
/*
* 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
{
// defines
var $_server;
var $_expire;
var $_db;
var $name;
var $msg;
// 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
$this->name = $name;
@@ -31,14 +42,20 @@ class session
array(&$this, "_gc")
);
// default lifetime on session cookie (SESSION_DAYS_TO_EXPIRE days)
// default lifetime on session cookie
session_set_cookie_params(
(60*60*24*SESSION_DAYS_TO_EXPIRE),
$this->_expire,
'/'
);
// start the loaded session
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)
@@ -57,52 +74,91 @@ class session
// destroy session
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)
function _close () { return true; }
// read session
function _read ($key)
// add alert message to buffer that will be displayed on the Next page view of the same user in html class
function addmsg ($text, $color = "black")
{
$result = query_parameters("SELECT data FROM session_list WHERE session_id = '?'", $key);
if (!$result) { return null; }
$oRow = query_fetch_object($result);
if($oRow)
return $oRow->data;
if (!isset($_SESSION['_msg']))
$_SESSION['_msg'] = array();
$_SESSION['_msg'][] = array(
'msg' => $text,
'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
return NULL;
}
// 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 ('?', '?', '?', '?', '?', ?)",
$key, $_SESSION['current']->iUserId, get_remote(), $value, $messages, "NOW()");
{
$this->_db->set($id, $data, null, $this->_expire);
}
return true;
}
// delete current session
function _destroy ($key)
// Delete the Session
function _destroy ($id)
{
query_parameters("DELETE FROM session_list WHERE session_id = '?'", $key);
return true;
return $this->_db->delete($id);
}
// clear old sessions (moved into a separate cron process)
// Garbage Collector (Not Needed for MemCache)
function _gc ($maxlifetime)
{
query_parameters("DELETE FROM session_list WHERE to_days(now()) - to_days(stamp) >= '?'",
SESSION_DAYS_TO_EXPIRE);
return true;
}

View File

@@ -13,7 +13,6 @@ drop table if exists appData;
drop table if exists appBundle;
drop table if exists appVotes;
drop table if exists appNotes;
drop table if exists sessionMessages;
/*
@@ -176,15 +175,3 @@ create table appNotes (
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 if they do not exist so we have to live with a potential
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
cat create_apidb_base.sql appdb_tables.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 \
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',
'user_list',
'user_privs',
'sessionMessages',
'vendor');
$this->update_counts();