Skip to content

Sequence cache #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ test/meta/Proto/
test/main/data/urls/parser.dump.new
.idea
test/onphp
/nbproject/

8 changes: 8 additions & 0 deletions core/Base/Assert.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,14 @@ public static function isUnreachable($message = 'unreachable code reached')
throw new WrongArgumentException($message);
}

public static function isObject($object, $message = null)
{
if (!is_object($object))
throw new WrongArgumentException(
$message.' not object given'
);
}

/// exceptionless methods
//@{
public static function checkInteger($value)
Expand Down
105 changes: 86 additions & 19 deletions core/Cache/PeclMemcached.class.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/***************************************************************************
* Copyright (C) 2006-2008 by Konstantin V. Arkhipov *
* Copyright (C) 2006-2012 by Konstantin V. Arkhipov *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
Expand All @@ -21,38 +21,36 @@ class PeclMemcached extends CachePeer
{
const DEFAULT_PORT = 11211;
const DEFAULT_HOST = '127.0.0.1';
const DEFAULT_TIMEOUT = 1;

private $instance = null;
private $instance = null;
private $requestTimeout = null;
private $connectTimeout = null;
private $host = null;
private $port = null;
private $triedConnect = false;

/**
* @return PeclMemcached
**/
public static function create(
$host = Memcached::DEFAULT_HOST,
$port = Memcached::DEFAULT_PORT
$port = Memcached::DEFAULT_PORT,
$connectTimeout = PeclMemcached::DEFAULT_TIMEOUT
)
{
return new self($host, $port);
return new self($host, $port, $connectTimeout);
}

public function __construct(
$host = Memcached::DEFAULT_HOST,
$port = Memcached::DEFAULT_PORT
$port = Memcached::DEFAULT_PORT,
$connectTimeout = PeclMemcached::DEFAULT_TIMEOUT
)
{
$this->instance = new Memcache();

try {
try {
$this->instance->pconnect($host, $port);
} catch (BaseException $e) {
$this->instance->connect($host, $port);
}

$this->alive = true;
} catch (BaseException $e) {
// bad luck.
}
$this->host = $host;
$this->port = $port;
$this->connectTimeout = $connectTimeout;
}

public function __destruct()
Expand All @@ -66,11 +64,20 @@ public function __destruct()
}
}

public function isAlive()
{
$this->ensureTriedToConnect();

return parent::isAlive();
}

/**
* @return PeclMemcached
**/
public function clean()
{
$this->ensureTriedToConnect();

try {
$this->instance->flush();
} catch (BaseException $e) {
Expand All @@ -82,6 +89,8 @@ public function clean()

public function increment($key, $value)
{
$this->ensureTriedToConnect();

try {
return $this->instance->increment($key, $value);
} catch (BaseException $e) {
Expand All @@ -91,6 +100,8 @@ public function increment($key, $value)

public function decrement($key, $value)
{
$this->ensureTriedToConnect();

try {
return $this->instance->decrement($key, $value);
} catch (BaseException $e) {
Expand All @@ -100,6 +111,8 @@ public function decrement($key, $value)

public function getList($indexes)
{
$this->ensureTriedToConnect();

return
($return = $this->get($indexes))
? $return
Expand All @@ -108,6 +121,8 @@ public function getList($indexes)

public function get($index)
{
$this->ensureTriedToConnect();

try {
return $this->instance->get($index);
} catch (BaseException $e) {
Expand All @@ -124,6 +139,8 @@ public function get($index)

public function delete($index)
{
$this->ensureTriedToConnect();

try {
// second parameter required, wrt new memcached protocol:
// delete key 0 (see process_delete_command in the memcached.c)
Expand All @@ -138,6 +155,8 @@ public function delete($index)

public function append($key, $data)
{
$this->ensureTriedToConnect();

try {
return $this->instance->append($key, $data);
} catch (BaseException $e) {
Expand All @@ -147,10 +166,58 @@ public function append($key, $data)
Assert::isUnreachable();
}

/**
* @param float $requestTimeout time in seconds
* @return PeclMemcached
*/
public function setTimeout($requestTimeout)
{
$this->ensureTriedToConnect();
$this->requestTimeout = $requestTimeout;
$this->instance->setServerParams($this->host, $this->port, $requestTimeout);

return $this;
}

/**
* @return float
*/
public function getTimeout()
{
return $this->requestTimeout;
}

protected function ensureTriedToConnect()
{
if ($this->triedConnect)
return $this;

$this->triedConnect = true;
$this->instance = new Memcache();

try {

try {
$this->instance->pconnect($this->host, $this->port, $this->connectTimeout);
} catch (BaseException $e) {
$this->instance->connect($this->host, $this->port, $this->connectTimeout);
}

$this->alive = true;

} catch (BaseException $e) {
// bad luck.
}

return $this;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не догнал. То есть в процессе работы мы можем менять параметры подключения - хост, порт, таймаут?
И после того как мы установили соединение $this->instance->pconnect() или $this->instance->connect() мы еще раз устанавливаем таймаут?
Зачем?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То есть в процессе работы мы можем менять параметры подключения - хост, порт, таймаут?

Не, не. Смысл в том, что подключение производится только при необходимости.

мы еще раз устанавливаем таймаут?

Это ошибка. На самом деле там два вида таймаута - таймаут на подключение и таймаут на запрос. Можно задать оба.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну да, не заметил что $this->instance->setServerParams() а не $this->setServerParams(),

protected function store(
$action, $key, $value, $expires = Cache::EXPIRES_MEDIUM
)
{
$this->ensureTriedToConnect();

try {
return
$this->instance->$action(
Expand All @@ -167,5 +234,5 @@ protected function store(

Assert::isUnreachable();
}

}
?>
132 changes: 132 additions & 0 deletions core/Cache/SequentialCache.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php
/****************************************************************************
* Copyright (C) 2012 by Artem Naumenko *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation; either version 3 of the *
* License, or (at your option) any later version. *
* *
****************************************************************************/

final class SequentialCache extends CachePeer
{
/**
* List of all peers, including master
* @var array of CachePeer
*/
private $list = array();

/**
* List of slaves only
* @var array of CachePeer
*/
private $slaves = array();

/**
* @var CachePeer
*/
private $master = null;

/**
* @param CachePeer $master
* @param array $slaves or CachePeer
* @return SequentialCache
*/
public static function create(CachePeer $master, array $slaves = array())
{
return new self($master, $slaves);
}

/**
* @param CachePeer $master
* @param array $slaves or CachePeer
*/
public function __construct(CachePeer $master, array $slaves = array())
{
$this->setMaster($master);

foreach ($slaves as $cache) {
$this->addPeer($cache);
}
}

/**
* @param CachePeer $master
* @return \SequentialCache
*/
public function setMaster(CachePeer $master)
{
$this->master = $master;
$this->list = $this->slaves;
array_unshift($this->list, $this->master);

return $this;
}

/**
* @param CachePeer $master
* @return \SequentialCache
*/
public function addPeer(CachePeer $peer)
{
$this->list[] = $peer;
$this->slaves[] = $peer;

return $this;
}

public function get($key)
{
foreach ($this->list as $val) {
/* @var $val CachePeer */
$result = $val->get($key);

if (
!empty($result)
|| $val->isAlive()
) {
return $result;
}
}

throw new RuntimeException('All peers are dead');
}

public function append($key, $data)
{
return $this->foreachItem(__METHOD__, func_get_args());
}

public function decrement($key, $value)
{
throw new UnsupportedMethodException('decrement is not supported');
}

public function delete($key)
{
return $this->foreachItem(__METHOD__, func_get_args());
}

public function increment($key, $value)
{
throw new UnsupportedMethodException('increment is not supported');
}

protected function store($action, $key, $value, $expires = Cache::EXPIRES_MEDIUM)
{
return $this->foreachItem(__METHOD__, func_get_args());
}

private function foreachItem($method, array $args)
{
$result = true;

foreach ($this->list as $peer) {
/* @var $peer CachePeer */
$result = call_user_func_array(array($peer, $method), $args) && $result;
}

return $result;
}
}
8 changes: 5 additions & 3 deletions main/Monitoring/PinbedPeclMemcached.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ final class PinbedPeclMemcached extends PeclMemcached
**/
public static function create(
$host = Memcached::DEFAULT_HOST,
$port = Memcached::DEFAULT_PORT
$port = Memcached::DEFAULT_PORT,
$connectTimeout = PeclMemcached::DEFAULT_TIMEOUT
)
{
return new self($host, $port);
}

public function __construct(
$host = Memcached::DEFAULT_HOST,
$port = Memcached::DEFAULT_PORT
$port = Memcached::DEFAULT_PORT,
$connectTimeout = PeclMemcached::DEFAULT_TIMEOUT
)
{
$this->host = $host;
Expand All @@ -42,7 +44,7 @@ public function __construct(
array('pecl_memcached_connect' => $host.'_'.$port)
);

parent::__construct($host, $port);
parent::__construct($host, $port, $connectTimeout);

if (PinbaClient::isEnabled())
PinbaClient::me()->timerStop(
Expand Down
Loading