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