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