]> git.mxchange.org Git - friendica.git/blob - src/Core/Lock/CacheLockDriver.php
Merge pull request #6744 from nupplaphil/task/namespace_to_class
[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, $override = false)
65         {
66                 $cachekey = self::getLockKey($key);
67
68                 if ($override) {
69                         $this->cache->delete($cachekey);
70                 } else {
71                         $this->cache->compareDelete($cachekey, getmypid());
72                 }
73                 $this->markRelease($key);
74         }
75
76         /**
77          * (@inheritdoc)
78          */
79         public function isLocked($key)
80         {
81                 $cachekey = self::getLockKey($key);
82                 $lock = $this->cache->get($cachekey);
83                 return isset($lock) && ($lock !== false);
84         }
85
86         /**
87          * @param string $key   The original key
88          * @return string               The cache key used for the cache
89          */
90         private static function getLockKey($key) {
91                 return "lock:" . $key;
92         }
93 }