We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

memcache and memcached

Hi, i'm trying to implement memcached cache in phalcon but it not work very well, so i've some suggestions:

  • memcache and libmemcached don't manage a possible down for a memcache server
  • if i want to manage it manually i can't use function like isStarted()(always false) or getLifetime() (always null)

so to implement memcache correctly i've to use the php library in the DI.

But if you have some tips for my situation I'd be very grateful

Thank you

The best solution i've found is to extend the Libmemcached class:

<?php

use Phalcon\Cache\Backend\Libmemcached;

class LibmemcachedPlugin extends Libmemcached
{
    public function isStarted()
    {
        $memcache = $this->_memcache;

        if (!is_object($memcache)) {
            $this->_connect();
            $memcache = $this->_memcache;
        }

        $stats = $memcache->getStats();
        foreach ($stats as $key => $value) {
            if ($stats[$key]['pid'] === -1) {
                return false;
            }
        }
        return true;
    }

    public function getStats()
    {
        $memcache = $this->_memcache;

        if (!is_object($memcache)) {
            $this->_connect();
            $memcache = $this->_memcache;
        }

        return $memcache->getStats();
    }
}

As I see, library does check whenever the connection is alive before trying to contact the daemon.

https://github.com/phalcon/cphalcon/blob/master/phalcon/cache/backend/libmemcached.zep#L136

But I guess you're talking about HA here, what happens if the daemon goes down. Since this is only a wrapper, there's no implementation for handling system level (daemon) processes, or even remote servers in case your memcacheD is hosted elsewhere.

That's why I implemented this in services container:

  // NOTE: exiting to command line puts too much overhead
     $libmemCheck = <<<DAEMON
ps -e | grep memcached | awk '{print $1}'
DAEMON;
    exec($libmemCheck, $rv, $status);
    !$status ? $pidMem = $rv[0] : $pidMem = 0x00;

    //you can also fetch the PID from file system and compare it with your ps command return value
    $pid = file_exists('/var/run/memcached.pid') ? file_get_contents('/var/run/memcached.pid') : false;

    //check process ID
    $pid = file_exists('/var/run/memcached.pid') ? true : false;
    //check socket
    $socketExists = file_exists($config->_daemon->socket) ? true : false; // socket defined as: /var/run/memcached.sock
    //throw exception if the daemon is N/A
    if (!$socketExists || !$pid) throw new \Phalcon\Exception('DAEMON is NaN!');

So, since I'm running on a same box, I do only this check which is the fastest and should at least catch daemon downtime.

 //check process ID
    $pid = file_exists('/var/run/memcached.pid') ? true : false;
    //check socket
    $socketExists = file_exists($config->_daemon->socket) ? true : false;
    //throw exception if the daemon is N/A
    if (!$socketExists || !$pid) throw new \Phalcon\Exception('DAEMON is NaN!');
    //now here we can try to start daemon again with either defining it in a php or to exec() system start.