3 namespace Friendica\Factory;
5 use Friendica\Core\Cache\IMemoryCache;
6 use Friendica\Core\Cache\Type;
7 use Friendica\Core\Config\IConfiguration;
8 use Friendica\Core\Lock;
9 use Friendica\Database\Database;
10 use Psr\Log\LoggerInterface;
15 * @package Friendica\Core\Cache
17 * A basic class to generate a LockDriver
22 * @var string The default driver for caching
24 const DEFAULT_DRIVER = 'default';
27 * @var IConfiguration The configuration to read parameters out of the config
32 * @var Database The database connection in case that the cache is used the dba connection
37 * @var CacheFactory The memory cache driver in case we use it
39 private $cacheFactory;
42 * @var LoggerInterface The Friendica Logger
46 public function __construct(CacheFactory $cacheFactory, IConfiguration $config, Database $dba, LoggerInterface $logger)
48 $this->cacheFactory = $cacheFactory;
49 $this->config = $config;
51 $this->logger = $logger;
54 public function create()
56 $lock_type = $this->config->get('system', 'lock_driver', self::DEFAULT_DRIVER);
64 $cache = $this->cacheFactory->create($lock_type);
65 if ($cache instanceof IMemoryCache) {
66 return new Lock\CacheLock($cache);
68 throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type));
73 return new Lock\DatabaseLock($this->dba);
77 return new Lock\SemaphoreLock();
81 return self::useAutoDriver();
83 } catch (\Exception $exception) {
84 $this->logger->alert('Driver \'' . $lock_type . '\' failed - Fallback to \'useAutoDriver()\'', ['exception' => $exception]);
85 return self::useAutoDriver();
90 * This method tries to find the best - local - locking method for Friendica
92 * The following sequence will be tried:
93 * 1. Semaphore Locking
99 private function useAutoDriver()
101 // 1. Try to use Semaphores for - local - locking
102 if (function_exists('sem_get')) {
104 return new Lock\SemaphoreLock();
105 } catch (\Exception $exception) {
106 $this->logger->debug('Using Semaphore driver for locking failed.', ['exception' => $exception]);
110 // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!)
111 $cache_type = $this->config->get('system', 'cache_driver', 'database');
112 if ($cache_type != Type::DATABASE) {
114 $cache = $this->cacheFactory->create($cache_type);
115 if ($cache instanceof IMemoryCache) {
116 return new Lock\CacheLock($cache);
118 } catch (\Exception $exception) {
119 $this->logger->debug('Using Cache driver for locking failed.', ['exception' => $exception]);
123 // 3. Use Database Locking as a Fallback
124 return new Lock\DatabaseLock($this->dba);