All pastes #2126812 Raw Edit

Mine

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