vendor/pimcore/pimcore/lib/Cache/Core/WriteLock.php line 124

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Cache\Core;
  15. use Psr\Log\LoggerAwareInterface;
  16. use Psr\Log\LoggerAwareTrait;
  17. use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
  18. /**
  19.  * @internal
  20.  */
  21. class WriteLock implements LoggerAwareInterface
  22. {
  23.     use LoggerAwareTrait;
  24.     /**
  25.      * @var bool
  26.      */
  27.     protected $enabled true;
  28.     /**
  29.      * @var TagAwareAdapterInterface
  30.      */
  31.     protected $itemPool;
  32.     /**
  33.      * @var string
  34.      */
  35.     protected $cacheKey 'system_cache_write_lock';
  36.     /**
  37.      * @var int
  38.      */
  39.     protected $lifetime 30;
  40.     /**
  41.      * Contains the timestamp of the write lock time from the current process
  42.      *
  43.      * This is to recheck when removing the write lock (if the value is different -> higher) do not remove the lock
  44.      * because then another process has acquired a lock.
  45.      *
  46.      * @var int|null
  47.      */
  48.     protected $timestamp;
  49.     /**
  50.      * @var bool
  51.      */
  52.     protected $lockInitialized false;
  53.     /**
  54.      * @param TagAwareAdapterInterface $itemPool
  55.      */
  56.     public function __construct(TagAwareAdapterInterface $itemPool)
  57.     {
  58.         $this->itemPool $itemPool;
  59.     }
  60.     /**
  61.      * {@inheritdoc}
  62.      */
  63.     public function enable()
  64.     {
  65.         $this->enabled true;
  66.     }
  67.     /**
  68.      * {@inheritdoc}
  69.      */
  70.     public function disable()
  71.     {
  72.         $this->enabled false;
  73.     }
  74.     /**
  75.      * {@inheritdoc}
  76.      */
  77.     public function isEnabled()
  78.     {
  79.         return $this->enabled;
  80.     }
  81.     /**
  82.      * Initialize lock value once from storage
  83.      */
  84.     protected function initializeLock()
  85.     {
  86.         if ($this->lockInitialized) {
  87.             return;
  88.         }
  89.         $item $this->itemPool->getItem($this->cacheKey);
  90.         if ($item->isHit()) {
  91.             $lock $item->get();
  92.             if ($this->isLockValid($lock)) {
  93.                 $this->timestamp $lock;
  94.             }
  95.         }
  96.         $this->lockInitialized true;
  97.     }
  98.     /**
  99.      * Set a write lock (prevents items being written to cache)
  100.      *
  101.      * @param bool $force
  102.      *
  103.      * @return bool
  104.      */
  105.     public function lock($force false)
  106.     {
  107.         if (!$this->enabled) {
  108.             return true;
  109.         }
  110.         $this->initializeLock();
  111.         if (!$this->timestamp || $force) {
  112.             $this->timestamp time();
  113.             $this->logger->debug(
  114.                 'Setting write lock with timestamp {timestamp}',
  115.                 ['timestamp' => $this->timestamp]
  116.             );
  117.             $item $this->itemPool->getItem($this->cacheKey);
  118.             $item->set($this->timestamp);
  119.             $item->expiresAfter($this->lifetime);
  120.             return $this->itemPool->save($item);
  121.         }
  122.         return false;
  123.     }
  124.     /**
  125.      * Check if a write lock is active
  126.      *
  127.      * @return bool
  128.      */
  129.     public function hasLock()
  130.     {
  131.         if (!$this->enabled || !$this->lockInitialized) {
  132.             return false;
  133.         }
  134.         if ($this->timestamp && $this->timestamp 0) {
  135.             return true;
  136.         }
  137.         $item $this->itemPool->getItem($this->cacheKey);
  138.         if ($item->isHit()) {
  139.             $lock $item->get();
  140.             if ($this->isLockValid($lock)) {
  141.                 $this->timestamp $lock;
  142.                 return true;
  143.             }
  144.         }
  145.         // normalize timestamp
  146.         $this->timestamp null;
  147.         return false;
  148.     }
  149.     /**
  150.      * @param int $lockTime
  151.      *
  152.      * @return bool
  153.      */
  154.     protected function isLockValid($lockTime)
  155.     {
  156.         return $lockTime > (time() - $this->lifetime);
  157.     }
  158.     /**
  159.      * Remove write lock from instance and from cache
  160.      *
  161.      * @return bool
  162.      */
  163.     public function removeLock()
  164.     {
  165.         if (!$this->enabled || !$this->lockInitialized) {
  166.             return true;
  167.         }
  168.         if ($this->timestamp) {
  169.             $item $this->itemPool->getItem($this->cacheKey);
  170.             if ($item->isHit()) {
  171.                 $lock $item->get();
  172.                 // only remove the lock if it was created by this process
  173.                 if ($lock <= $this->timestamp) {
  174.                     $this->logger->debug(
  175.                         'Removing write lock with timestamp {timestamp}',
  176.                         ['timestamp' => $lock]
  177.                     );
  178.                     $this->itemPool->deleteItem($this->cacheKey);
  179.                     $this->timestamp null;
  180.                     return true;
  181.                 } else {
  182.                     $this->logger->debug(
  183.                         'Not removing write lock as timestamp does not belong to this process (timestamp: {timestamp}, lock: {lock})',
  184.                         ['timestamp' => $this->timestamp'lock' => $lock]
  185.                     );
  186.                     return false;
  187.                 }
  188.             }
  189.         }
  190.         return false;
  191.     }
  192. }