]> git.mxchange.org Git - friendica.git/blob - src/Core/Lock.php
code standards / simplifications
[friendica.git] / src / Core / Lock.php
1 <?php
2 /**
3  * @file src/Util/Lock.php
4  */
5 namespace Friendica\Core;
6
7 /**
8  * @file src/Core/Lock.php
9  * @brief Functions for preventing parallel execution of functions
10  */
11
12 use Friendica\Core\Cache\CacheDriverFactory;
13 use Friendica\Core\Cache\IMemoryCacheDriver;
14
15 /**
16  * @brief This class contain Functions for preventing parallel execution of functions
17  */
18 class Lock
19 {
20         /**
21          * @var Lock\ILockDriver;
22          */
23         static $driver = null;
24
25         public static function init()
26         {
27                 $lock_driver = Config::get('system', 'lock_driver', 'default');
28
29                 try {
30                         switch ($lock_driver) {
31                                 case 'memcache':
32                                 case 'memcached':
33                                 case 'redis':
34                                         $cache_driver = CacheDriverFactory::create($lock_driver);
35                                         if ($cache_driver instanceof IMemoryCacheDriver) {
36                                                 self::$driver = new Lock\CacheLockDriver($cache_driver);
37                                         }
38                                         break;
39
40                                 case 'database':
41                                         self::$driver = new Lock\DatabaseLockDriver();
42                                         break;
43
44                                 case 'semaphore':
45                                         self::$driver = new Lock\SemaphoreLockDriver();
46                                         break;
47
48                                 default:
49                                         self::useAutoDriver();
50                         }
51                 } catch (\Exception $exception) {
52                         logger ('Driver \'' . $lock_driver . '\' failed - Fallback to \'useAutoDriver()\'');
53                         self::useAutoDriver();
54                 }
55         }
56
57         /**
58          * @brief This method tries to find the best - local - locking method for Friendica
59          *
60          * The following sequence will be tried:
61          * 1. Semaphore Locking
62          * 2. Cache Locking
63          * 3. Database Locking
64          *
65          */
66         private static function useAutoDriver() {
67
68                 // 1. Try to use Semaphores for - local - locking
69                 if (function_exists('sem_get')) {
70                         try {
71                                 self::$driver = new Lock\SemaphoreLockDriver();
72                                 return;
73                         } catch (\Exception $exception) {
74                                 logger ('Using Semaphore driver for locking failed: ' . $exception->getMessage());
75                         }
76                 }
77
78                 // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!)
79                 $cache_driver = Config::get('system', 'cache_driver', 'database');
80                 if ($cache_driver != 'database') {
81                         try {
82                                 $lock_driver = CacheDriverFactory::create($cache_driver);
83                                 if ($lock_driver instanceof IMemoryCacheDriver) {
84                                         self::$driver = new Lock\CacheLockDriver($lock_driver);
85                                 }
86                                 return;
87                         } catch (\Exception $exception) {
88                                 logger('Using Cache driver for locking failed: ' . $exception->getMessage());
89                         }
90                 }
91
92                 // 3. Use Database Locking as a Fallback
93                 self::$driver = new Lock\DatabaseLockDriver();
94         }
95
96         /**
97          * Returns the current cache driver
98          *
99          * @return Lock\ILockDriver;
100          */
101         private static function getDriver()
102         {
103                 if (self::$driver === null) {
104                         self::init();
105                 }
106
107                 return self::$driver;
108         }
109
110         /**
111          * @brief Acquires a lock for a given name
112          *
113          * @param string  $key Name of the lock
114          * @param integer $timeout Seconds until we give up
115          *
116          * @return boolean Was the lock successful?
117          */
118         public static function acquireLock($key, $timeout = 120)
119         {
120                 return self::getDriver()->acquire($key, $timeout);
121         }
122
123         /**
124          * @brief Releases a lock if it was set by us
125          *
126          * @param string $key Name of the lock
127          * @return mixed
128          */
129         public static function releaseLock($key)
130         {
131                 return self::getDriver()->release($key);
132         }
133
134         /**
135          * @brief Releases all lock that were set by us
136          * @return void
137          */
138         public static function releaseAll()
139         {
140                 self::getDriver()->releaseAll();
141         }
142 }