devilbox/.devilbox/www/include/lib/container/Memcd.php

230 lines
5.6 KiB
PHP
Raw Normal View History

2017-05-06 09:13:33 +00:00
<?php
namespace devilbox;
/**
* @requires devilbox::Logger
*/
2017-05-15 06:56:17 +00:00
class Memcd extends BaseClass implements BaseInterface
2017-05-06 09:13:33 +00:00
{
/*********************************************************************************
*
* Private Variables
*
*********************************************************************************/
/**
* Memcached instance
* @var object|null
*/
private $_memcached = null;
/*********************************************************************************
*
2017-05-15 06:56:17 +00:00
* Constructor Overwrite
2017-05-06 09:13:33 +00:00
*
*********************************************************************************/
/**
* Use singleton getInstance() instead.
*
* @param string $user Username
* @param string $pass Password
* @param string $host Host
*/
2017-05-15 06:56:17 +00:00
public function __construct($hostname, $data = array())
2017-05-06 09:13:33 +00:00
{
2017-05-15 06:56:17 +00:00
parent::__construct($hostname, $data);
if (class_exists('Memcached')) {
$memcd = new \Memcached('_devilbox');
$list = $memcd->getServerList();
if (empty($list)) {
$memcd->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
2018-12-10 19:09:09 +00:00
$memcd->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$memcd->addServer($hostname, 11211);
}
2017-05-06 09:13:33 +00:00
$err = false;
$stats = $memcd->getStats();
if (!isset($stats[$hostname.':11211'])) {
$memcd->quit();
$this->_connect_error = 'Failed to connect to Memcached host on '.$hostname.' (no connection array)';
$this->_connect_errno = 1;
return;
}
else if (!isset($stats[$hostname.':11211']['pid'])) {
$memcd->quit();
$this->_connect_error = 'Failed to connect to Memcached host on '.$hostname.' (no pid)';
$this->_connect_errno = 2;
return;
}
else if ($stats[$hostname.':11211']['pid'] < 1) {
$memcd->quit();
$this->_connect_error = 'Failed to connect to Memcached host on '.$hostname.' (invalid pid)';
$this->_connect_errno = 3;
return;
}
2018-12-10 19:09:09 +00:00
$memcd->getDelayed(array('devilbox-version'));
if (!$memcd->fetchAll()) {
$memcd->set('devilbox-version', $GLOBALS['DEVILBOX_VERSION'].' ('.$GLOBALS['DEVILBOX_DATE'].')');
}
$this->_memcached = $memcd;
} else {
$ret = 0;
2018-12-10 19:09:09 +00:00
loadClass('Helper')->exec('echo "stats" | nc '.$hostname.' 11211', $ret);
if ($ret == 0) {
$this->_memcached = true;
}
}
2017-05-06 09:13:33 +00:00
}
/**
* Destructor
*/
public function __destruct()
{
if (class_exists('Memcached')) {
if ($this->_memcached) {
$this->_memcached->quit();
}
2017-05-06 09:13:33 +00:00
}
}
2017-05-15 06:56:17 +00:00
2017-05-06 09:13:33 +00:00
/*********************************************************************************
*
2017-05-15 06:56:17 +00:00
* Select functions
2017-05-06 09:13:33 +00:00
*
*********************************************************************************/
2017-05-07 16:49:38 +00:00
public function getKeys()
2017-05-06 09:13:33 +00:00
{
2017-05-07 16:49:38 +00:00
$store = array();
if (class_exists('Memcached')) {
if ($this->_memcached) {
2018-12-10 19:09:09 +00:00
$this->_memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true);
$output = array();
exec('printf "stats cachedump 1 0\nquit\n" | nc memcd 11211 | grep -E \'^ITEM\'', $output);
foreach ($output as $line) {
$matches = array();
preg_match('/(^ITEM)\s*(.+?)\s*\[([0-9]+\s*b);\s*([0-9]+\s*s)\s*\]/', $line, $matches);
$key = $matches[2];
$store[] = array(
'key' => $key,
'size' => $matches[3],
'ttl' => $matches[4],
'val' => $this->_memcached->get($key)
);
}
2018-12-10 19:09:09 +00:00
return $store;
2017-05-07 16:49:38 +00:00
}
2017-05-06 09:13:33 +00:00
}
2017-05-07 16:49:38 +00:00
return $store;
2017-05-06 09:13:33 +00:00
}
2017-05-07 16:49:38 +00:00
public function getInfo()
2017-05-06 09:13:33 +00:00
{
$stats = array();
if (class_exists('Memcached')) {
if ($this->_memcached) {
$stats = $this->_memcached->getStats();
}
} else {
$ret = 0;
2018-12-10 19:09:09 +00:00
$output = loadClass('Helper')->exec('echo "stats" | nc memcd 11211 | sed "s/^STAT[[:space:]]*//g" | grep -v "END"', $ret);
if ($ret == 0) {
$output = explode("\n", $output);
foreach ($output as $line) {
$tmp = explode(' ', $line);
$key = isset($tmp[0]) ? $tmp[0] : '';
$val = isset($tmp[1]) ? $tmp[1] : '';
2018-12-10 19:09:09 +00:00
$stats['memcd'][$key] = $val;
}
}
}
2017-05-07 16:49:38 +00:00
return $stats;
}
2017-05-06 09:13:33 +00:00
/*********************************************************************************
*
* Interface required functions
*
*********************************************************************************/
2017-05-15 06:56:17 +00:00
private $_can_connect = array();
private $_can_connect_err = array();
private $_name = null;
private $_version = null;
public function canConnect(&$err, $hostname, $data = array())
{
$err = false;
// Return if already cached
if (isset($this->_can_connect[$hostname])) {
// Assume error for unset error message
$err = isset($this->_can_connect_err[$hostname]) ? $this->_can_connect_err[$hostname] : true;
return $this->_can_connect[$hostname];
}
2018-12-10 19:09:09 +00:00
$ret = 0;
loadClass('Helper')->exec('echo "stats" | nc '.$hostname.' 11211', $ret);
if ($ret == 0) {
$this->_can_connect[$hostname] = true;
} else {
2018-12-10 19:09:09 +00:00
$err = 'Failed to connect to Memcached host on '.$hostname;
$this->_can_connect[$hostname] = false;
2017-05-15 06:56:17 +00:00
}
return $this->_can_connect[$hostname];
}
2017-05-06 09:13:33 +00:00
public function getName($default = 'Memcached')
{
return $default;
}
public function getVersion()
{
2017-05-15 06:56:17 +00:00
// Return if already cached
if ($this->_version !== null) {
return $this->_version;
}
// Return empty if not available
if (!$this->isAvailable()) {
$this->_version = '';
return $this->_version;
}
if (class_exists('Memcached')) {
if ($this->_memcached) {
$info = $this->_memcached->getVersion();
$info = array_values($info);
if (!isset($info[0])) {
loadClass('Logger')->error('Could not get Memcached version');
$this->_version = '';
} else {
$this->_version = $info[0];
}
}
} else {
2018-12-10 19:09:09 +00:00
$version = loadClass('Helper')->exec('echo "version" | nc memcd 11211 | grep -oE "[0-9.-]+"', $ret);
$this->_version = $version;
2017-05-06 09:13:33 +00:00
}
2017-05-15 06:56:17 +00:00
return $this->_version;
2017-05-06 09:13:33 +00:00
}
}