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