]> git.mxchange.org Git - friendica.git/blob - src/Core/Lock/CacheLockDriver.php
coding standards
[friendica.git] / src / Core / Lock / CacheLockDriver.php
1 <?php
2
3 namespace Friendica\Core\Lock;
4
5 use Friendica\Core\Cache;
6 use Friendica\Core\Cache\IMemoryCacheDriver;
7
8 class CacheLockDriver extends AbstractLockDriver
9 {
10         /**
11          * @var \Friendica\Core\Cache\ICacheDriver;
12          */
13         private $cache;
14
15         /**
16          * CacheLockDriver constructor.
17          *
18          * @param IMemoryCacheDriver $cache The CacheDriver for this type of lock
19          */
20         public function __construct(IMemoryCacheDriver $cache)
21         {
22                 $this->cache = $cache;
23         }
24
25         /**
26          * (@inheritdoc)
27          */
28         public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
29         {
30                 $got_lock = false;
31                 $start = time();
32
33                 $cachekey = self::getLockKey($key);
34
35                 do {
36                         $lock = $this->cache->get($cachekey);
37                         // When we do want to lock something that was already locked by us.
38                         if ((int)$lock == getmypid()) {
39                                 $got_lock = true;
40                         }
41
42                         // When we do want to lock something new
43                         if (is_null($lock)) {
44                                 // At first initialize it with "0"
45                                 $this->cache->add($cachekey, 0);
46                                 // Now the value has to be "0" because otherwise the key was used by another process meanwhile
47                                 if ($this->cache->compareSet($cachekey, 0, getmypid(), $ttl)) {
48                                         $got_lock = true;
49                                         $this->markAcquire($key);
50                                 }
51                         }
52
53                         if (!$got_lock && ($timeout > 0)) {
54                                 usleep(rand(10000, 200000));
55                         }
56                 } while (!$got_lock && ((time() - $start) < $timeout));
57
58                 return $got_lock;
59         }
60
61         /**
62          * (@inheritdoc)
63          */
64         public function releaseLock($key)
65         {
66                 $cachekey = self::getLockKey($key);
67
68                 $this->cache->compareDelete($cachekey, getmypid());
69                 $this->markRelease($key);
70         }
71
72         /**
73          * (@inheritdoc)
74          */
75         public function isLocked($key)
76         {
77                 $cachekey = self::getLockKey($key);
78                 $lock = $this->cache->get($cachekey);
79                 return isset($lock) && ($lock !== false);
80         }
81
82         /**
83          * @param string $key   The original key
84          * @return string               The cache key used for the cache
85          */
86         private static function getLockKey($key) {
87                 return "lock:" . $key;
88         }
89 }