You are here

class MemcacheLockBackend in Memcache API and Integration 8.2

Defines a Memcache lock backend.

Hierarchy

Expanded class hierarchy of MemcacheLockBackend

File

src/Lock/MemcacheLockBackend.php, line 11

Namespace

Drupal\memcache\Lock
View source
class MemcacheLockBackend extends LockBackendAbstract {

  /**
   * An array of currently acquired locks.
   *
   * @var array
   */
  protected $locks = [];

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

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

  /**
   * Constructs a new MemcacheLockBackend.
   *
   * @param string $bin
   *   The bin name for this lock.
   * @param \Drupal\memcache\DrupalMemcacheInterface $memcache
   *   The memcache wrapper object.
   */
  public function __construct($bin, DrupalMemcacheInterface $memcache) {
    $this->bin = $bin;
    $this->memcache = $memcache;

    // __destruct() is causing problems with garbage collections, register a
    // shutdown function instead.
    drupal_register_shutdown_function([
      $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 (isset($this->locks[$name])) {

      // Try to extend the expiration of a lock we already acquired.
      $success = !$this
        ->lockMayBeAvailable($name) && $this->memcache
        ->set($name, $lock_id, $timeout);
      if (!$success) {

        // The lock was broken.
        unset($this->locks[$name]);
      }
      return $success;
    }
    else {
      if ($this
        ->lockMayBeAvailable($name)) {
        $success = $this->memcache
          ->add($name, $lock_id, $timeout);
        if (!$success) {
          return FALSE;
        }

        // We track all acquired locks in the global variable, if successful.
        $this->locks[$name] = TRUE;
      }
      else {
        return FALSE;
      }
    }
    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) {
    if (empty($lock_id)) {
      $lock_id = $this
        ->getLockId();
    }
    foreach ($this->locks as $name => $id) {
      $value = $this->memcache
        ->get($name);
      if ($value == $lock_id) {
        $this->memcache
          ->delete($name);
      }
    }
    $this->locks = [];
  }

}

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.