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; } } }