[imp] memcached sessions

liam hoekenga liamr at umich.edu
Fri Oct 28 14:56:03 PDT 2005


>> You could also try using the mcache extension
>> (http://www.klir.com/~johnm/php-mcache/) instead of the memcached
>> extension.  mcache wraps libmemcache, and unlike the memcached extesion,
>> it supports pooled servers.

As of 1.2.0b10, it looks like it's mostly working w/ my modified 
memcache sessionhandler and a pool of servers.  I've attached the one 
I'm working with currently.

The mcache extension doesn't do compression natively, so you'd have to 
(un)compress the data as it's transmitted.  The error condition also 
doesn't seem to pick up when it's tried to connect to a server it 
can't, while the extension itself does report this error:

[Fri Oct 28 17:45:54 2005] [error] PHP Warning:  
mcm_server_add3():2076: unable to lookup/resolve host: Name or service 
not known

It's probably due to this in bit described in the example code:

	 * add_server() returns TRUE on success, and FALSE on failure.         
  * Because an actual connection is not immediately attempted,         
* this should always return TRUE except in the event of an internal
         * error.

Seems like it could be problematic.

Otherwise, most of the function calls are pretty easily translated to 
the mcache extension from the memcache extension, and most expect the 
same arguements.

I have not queried the servers in my pool to see if they actually all 
contain the session data I'm working with.. but it looks promising.

Liam
-------------- next part --------------
<?php
/**
 * SessionHandler:: implementation for memcached.
 * memcached website: http://www.danga.com/memcached/
 *
 * Required parameters:<pre>
 *   'hostspec'  The hostname of the memcached server.
 *   'port'      The port on which to connect to the memcached server.</pre>
 *
 * $Horde: framework/SessionHandler/SessionHandler/memcached.php,v 1.8.2.1 2005/06/26 04:28:31 chuck Exp $
 *
 * Copyright 2005 Rong-En Fan <rafan at infor.org>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Rong-En Fan <rafan at infor.org>
 * @since   Horde 3.1
 * @package Horde_SessionHandler
 */
class SessionHandler_mcache extends SessionHandler {

    /**
     * Current memcached connection.
     *
     * @var resource
     */
    var $_db;

    /**
     * Boolean indicating whether or not we're connected to the SQL server.
     *
     * @var boolean
     */
    var $_connected = false;

    /**
     * Read the data for a particular session identifier from the
     * SessionHandler backend.
     *
     * @param string $id  The session identifier.
     *
     * @return string  The session data.
     */
    function read($id)
    {
        /* Make sure we have a valid database connection. */
        $this->_connect();

        $result = $this->_db->get($id);

        if (!$result) {
            Horde::logMessage('Error retrieving session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
            return false;
        }

        return $result;
    }

    /**
     * Write session data to the SessionHandler backend.
     *
     * @param string $id            The session identifier.
     * @param string $session_data  The session data.
     *
     * @return boolean  True on success, false otherwise.
     */
    function write($id, $session_data)
    {
        /* Make sure we have a valid database connection. */
        $this->_connect();

        $lifetime = ini_get('session.gc_maxlifetime');
        $result = $this->_db->set($id, $session_data);

        if (!$result) {
            Horde::logMessage('Error writing session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
            return false;
        }

        return true;
    }

    /**
     * Destroy the data for a particular session identifier in the
     * SessionHandler backend.
     *
     * @param string $id  The session identifier.
     *
     * @return boolean  True on success, false otherwise.
     */
    function destroy($id)
    {
        /* Make sure we have a valid database connection. */
        $this->_connect();

        $result = $this->_db->delete($id);

        if (!$result) {
            Horde::logMessage('Failed to delete session (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
            return false;
        }

        return true;
    }

    /**
     * Garbage collect stale sessions from the SessionHandler backend.
     *
     * @param integer $maxlifetime  The maximum age of a session.
     *
     * @return boolean  True on success, false otherwise.
     */
    function gc($maxlifetime = 300)
    {
        return true;
    }

    /**
     * Attempts to open a connection to the memcached server.
     *
     * @access private
     */
    function _connect()
    {
        if ($this->_connected) {
            return;
        }

        Horde::assertDriverConfig($this->_params, 'sessionhandler',
            array('hostspec', 'port'),
            'session handler mcache');

	$this->_db = memcache();
        for ($i = 0, $n = count($this->_params['hostspec']); $i < $n; $i++) {
            if (!$this->_db->add_server($this->_params['hostspec'][$i],
                                  $this->_params['port'][$i])) {
                Horde::logMessage('Could not connect to memcached for mcache SessionHandler at ' . $this->_params['hostspec'][$i] . ':' . $this->_params['port'][$i] , __FILE__, __LINE__,PEAR_LOG_ERR);
            } else {  
                Horde::logMessage('Connected to memcached for mcache SessionHandler at ' . $this->_params['hostspec'][$i] . ':' . $this->_params['port'][$i] , __FILE__, __LINE__, PEAR_LOG_DEBUG);
                $this->_connected = true;
            }      
	}

    }

}


More information about the imp mailing list