rendered paste body<?php
class ConnectionHandler {
const DB_LOCK_PREFIX = 'DBCHL:'; // DB Connection Handler Lock
const REDIS_LOCK_PREFIX = 'RCHL:'; // Redis Connection Handler Lock
private $instance = null;
private $lock_key = null;
private $lock_prefix = null;
private $redis = null;
public function getLockKey() {
return $this->lock_key;
}
public static function getCHandler($obj, $prefix) {
return new self($obj, $prefix);
}
public function __construct($obj, $prefix) {
if($prefix === self::DB_LOCK_PREFIX) {
$this->redis = RedisMapper::getPersistent(Config::KEYSPACE_DB_LOCKS);
}
else if($prefix === self::REDIS_LOCK_PREFIX) {
// TODO: а нужен ли для редиса модуль блокировки?
$this->redis = RedisMapper::getPersistent(Config::KEYSPACE_REDIS_LOCKS);
}
$this->lock_prefix = $prefix;
$this->instance = $obj;
$this->lock_key = $prefix . $obj->getId();
$this->instance->setHandler($this);
$this->regenerateKey();
}
public function regenerateKey() {
$new_key = $this->lock_prefix . $this->instance->getId();
$this->redis->setNx($new_key, true);
if(null !== $this->lock_key) {
$this->redis->del($this->lock_key);
}
$this->lock_key = $new_key;
}
public function __call($f, array $args) {
$mExists = (!method_exists($this->instance, $f) && ($this->instance instanceof RedisClient && !method_exists($this->instance->getObj(), $f)));
if($mExists) {
Daemon::log(__CLASS__.'('.__LINE__.')'."===========================");
Daemon::log(__CLASS__.'('.__LINE__.')'."Traceback: \n".debug_backtrace());
trigger_error('Call undefined method '.$f.'() in object of class "'.get_class($this->instance).'"', E_USER_NOTICE);
return;
}
return call_user_func_array(array($this->instance, $f), $args);
}
public function acquire() {
$ret = $this->redis->setNx($this->lock_key, Debug::backtrace());
if($ret) {
$this->redis->expireAt($this->lock_key, time() + 10);
}
return $ret;
}
public function validate() {
// TODO: провалидировать объект.
}
public function release() {
$this->redis->del($this->lock_key);
}
public function __destruct() {
$this->tearDown();
}
public function tearDown() {
if(($this->instance instanceof RedisClient) || ($this->instance instanceof DB)) {
$this->instance->tearDown();
$this->instance = null;
}
if($this->redis instanceof RedisClient) {
$this->redis->close();
$this->redis = null;
}
}
}