rendered paste body<?php
/**
* Класс обертка для работы с редисом, необходима для бенчмаркинга (нужно доделать),
* а также для учета ситуаций, когда соединение по каким-то причинам было оборвано
*/
class RedisClient {
const REQUEST_STATE_OK = 1;
const REQUEST_STATE_FAIL = 2;
const MAX_TRIES_COUNT = 3;
const PONG = "+PONG";
protected $id;
protected $host;
protected $port;
protected $socket;
protected $db;
protected $handler;
public function __construct($host, $port, $socket, $db, $serializer = Redis::SERIALIZER_IGBINARY) {
$this->host = $host;
$this->port = $port;
$this->socket = $socket;
$this->db = $db;
$this->id = md5(microtime().mt_rand().(mt_rand() / mt_getrandmax()).microtime(true));
$this->init();
}
protected function init() {
$this->handler = new Redis();
}
protected function checkConnection() {
if(is_object($this->handler)) {
return true;
}
}
protected function cycledOp($op, array $args, $opLimit = self::MAX_TRIES_COUNT) {
$count = 0;
$ret = false;
$rstate = self::REQUEST_STATE_OK;
do {
try {
$ret = call_user_func_array($op, $args);
$rstate = self::REQUEST_STATE_OK;
break;
} catch(Exception $e) {
$ret = false;
++$count;
$rstate = self::REQUEST_STATE_FAIL;
Daemon::log('Error in redis op. Reason: '.$e->getMessage().'. Op: '.Debug::dump($op).'. Args: '.Debug::dump($args).' From: '.Debug::backtrace());
$this->ping();
}
} while($count < $opLimit);
if($rstate == self::REQUEST_STATE_FAIL) {
Daemon::log('Epic FAIL: '.Debug::dump($op).Debug::backtrace());
}
return $ret;
}
public function __call($f, array $args) {
if(!method_exists($this->handler, $f)) {
Daemon::log('Try to call unknown method "'.$f.'" of Redis from: '.Debug::backtrace());
return false;
}
return $this->cycledOp(array($this->handler, $f), $args);
}
public function connect() {
$this->close();
$callback = array($this->handler, 'connect');
$args = array($this->host, $this->port, Config::REDIS_CONNECTION_TIMEOUT);
$opCount = 0;
$maxOpCount = self::MAX_TRIES_COUNT;
do {
++$opCount;
try {
$ret = $this->handler->connect($this->host, $this->port, Config::REDIS_CONNECTION_TIMEOUT);
if($ret) {
break;
}
} catch(Exception $e) {
Daemon::log('Error on RedisConnect('.$this->port.'). Reason: '.$e->getMessage());
}
} while($opCount < $maxOpCount);
return;
}
public function ping() {
try {
if($this->handler->ping() == self::PONG) {
return true;
}
} catch(Exception $e) {
//$this->close();
//$this->init();
Daemon::log('Error on ping! '.Debug::backtrace());
return $this->connect();
}
}
public function close() {
try {
$this->handler->close();
} catch(Exception $e) {
// nothing do
}
}
public function getObj() {
return $this->handler;
}
public function getId() {
return $this->id;
}
public function setHandler() {
return;
}
public function setKeyExpire($key, $ttl) {
$this->expire($key, $ttl);
}
public function regenerateKey() {
return;
}
public function tearDown() {
$this->close();
$this->handler = null;
}
public function isValid() {
return $this->port == 6300;
}
}