All pastes #2126814 Raw Edit

Mine

public text v1 · immutable
#2126814 ·published 2012-03-11 13:14 UTC
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;
  }
}