cacheFactory = $cacheFactory; $this->config = $config; $this->dba = $dba; $this->logger = $logger; } public function create() { $lock_type = $this->config->get('system', 'lock_driver', self::DEFAULT_DRIVER); try { switch ($lock_type) { case AbstractCache::TYPE_MEMCACHE: case AbstractCache::TYPE_MEMCACHED: case AbstractCache::TYPE_REDIS: case AbstractCache::TYPE_APCU: $cache = $this->cacheFactory->create($lock_type); if ($cache instanceof IMemoryCache) { return new Lock\CacheLock($cache); } else { throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type)); } break; case 'database': return new Lock\DatabaseLock($this->dba); break; case 'semaphore': return new Lock\SemaphoreLock(); break; default: return self::useAutoDriver(); } } catch (\Exception $exception) { $this->logger->alert('Driver \'' . $lock_type . '\' failed - Fallback to \'useAutoDriver()\'', ['exception' => $exception]); return self::useAutoDriver(); } } /** * @brief This method tries to find the best - local - locking method for Friendica * * The following sequence will be tried: * 1. Semaphore Locking * 2. Cache Locking * 3. Database Locking * * @return Lock\ILock */ private function useAutoDriver() { // 1. Try to use Semaphores for - local - locking if (function_exists('sem_get')) { try { return new Lock\SemaphoreLock(); } catch (\Exception $exception) { $this->logger->debug('Using Semaphore driver for locking failed.', ['exception' => $exception]); } } // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!) $cache_type = $this->config->get('system', 'cache_driver', 'database'); if ($cache_type != AbstractCache::TYPE_DATABASE) { try { $cache = $this->cacheFactory->create($cache_type); if ($cache instanceof IMemoryCache) { return new Lock\CacheLock($cache); } } catch (\Exception $exception) { $this->logger->debug('Using Cache driver for locking failed.', ['exception' => $exception]); } } // 3. Use Database Locking as a Fallback return new Lock\DatabaseLock($this->dba); } }