You are here

class MemcacheLockBackend in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 modules/memcache/src/MemcacheLockBackend.php \Drupal\memcache\MemcacheLockBackend

Defines a Memcache lock backend.

Hierarchy

Expanded class hierarchy of MemcacheLockBackend

File

modules/memcache/src/MemcacheLockBackend.php, line 15
Contains \Drupal\memcache\MemcacheLockBackend.

Namespace

Drupal\memcache
View source
class MemcacheLockBackend extends LockBackendAbstract {

  /**
   * An array of currently acquired locks.
   *
   * @var array
   */
  protected $locks = array();

  /**
   * The bin name for this lock.
   *
   * @var string
   */
  protected $bin = 'semaphore';

  /**
   * The memcache wrapper object.
   *
   * @var \Drupal\memcache\DrupalMemcacheInterface
   */
  protected $memcache;

  /**
   * Constructs a new MemcacheLockBackend.
   */
  public function __construct(DrupalMemcacheFactory $memcache_factory) {
    $this->memcache = $memcache_factory
      ->get($this->bin);

    // __destruct() is causing problems with garbage collections, register a
    // shutdown function instead.
    drupal_register_shutdown_function(array(
      $this,
      'releaseAll',
    ));
  }

  /**
   * {@inheritdoc}
   */
  public function acquire($name, $timeout = 30.0) {

    // Ensure that the timeout is at least 1 sec. This is a limitation imposed
    // by memcached.
    $timeout = (int) max($timeout, 1);
    $lock_id = $this
      ->getLockId();
    if ($this->memcache
      ->set($name, $lock_id, $timeout)) {
      $this->locks[$name] = $lock_id;
    }
    elseif (($result = $this->memcache
      ->get($name)) && isset($this->locks[$name]) && $this->locks[$name] == $lock_id) {

      // Only renew the lock if we already set it and it has not expired.
      $this->memcache
        ->set($name, $lock_id, $timeout);
    }
    else {

      // Failed to acquire the lock. Unset the key from the $locks array even if
      // not set.
      unset($this->locks[$name]);
    }
    return isset($this->locks[$name]);
  }

  /**
   * {@inheritdoc}
   */
  public function lockMayBeAvailable($name) {
    return !$this->memcache
      ->get($name);
  }

  /**
   * {@inheritdoc}
   */
  public function release($name) {
    $this->memcache
      ->delete($name);

    // We unset unconditionally since caller assumes lock is released anyway.
    unset($this->locks[$name]);
  }

  /**
   * {@inheritdoc}
   */
  public function releaseAll($lock_id = NULL) {
    foreach ($this->locks as $name => $id) {
      $value = $this->memcache
        ->get($name);
      if ($value == $id) {
        $this->memcache
          ->delete($name);
      }
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
LockBackendAbstract::$lockId protected property Current page lock token identifier.
LockBackendAbstract::getLockId public function Gets the unique page token for locks. Overrides LockBackendInterface::getLockId
LockBackendAbstract::wait public function Waits a short amount of time before a second lock acquire attempt. Overrides LockBackendInterface::wait
MemcacheLockBackend::$bin protected property The bin name for this lock.
MemcacheLockBackend::$locks protected property An array of currently acquired locks. Overrides LockBackendAbstract::$locks
MemcacheLockBackend::$memcache protected property The memcache wrapper object.
MemcacheLockBackend::acquire public function Acquires a lock. Overrides LockBackendInterface::acquire
MemcacheLockBackend::lockMayBeAvailable public function Checks if a lock is available for acquiring. Overrides LockBackendInterface::lockMayBeAvailable
MemcacheLockBackend::release public function Releases the given lock. Overrides LockBackendInterface::release
MemcacheLockBackend::releaseAll public function Releases all locks for the given lock token identifier. Overrides LockBackendInterface::releaseAll
MemcacheLockBackend::__construct public function Constructs a new MemcacheLockBackend.