<?php
-/**
- * @file src/Core/Lock.php
- */
-namespace Friendica\Util;
/**
* @file src/Core/Lock.php
* @brief Functions for preventing parallel execution of functions
*/
-use Friendica\Core\Config;
-use Friendica\Core\Lock;
+namespace Friendica\Core;
-require_once 'include/dba.php';
+use Friendica\Core\Cache\CacheDriverFactory;
+use Friendica\Core\Cache\IMemoryCacheDriver;
/**
* @brief This class contain Functions for preventing parallel execution of functions
public static function init()
{
- switch(Config::get('system', 'lock_driver', 'default')) {
- case 'memcache':
- self::$driver = new Lock\MemcacheLockDriver();
- break;
- case 'database':
- self::$driver = new Lock\DatabaseLockDriver();
- break;
- case 'semaphore':
- self::$driver = new Lock\SemaphoreLockDriver();
- break;
- default:
- // Determine what's the best/fastest locking driver (default behavior in Friendica)
- if (function_exists('sem_get') && version_compare(PHP_VERSION, '5.6.1', '>=')) {
- self::$driver = new Lock\SemaphoreLockDriver();
- } elseif (Config::get('system', 'cache_driver', 'database') == 'memcache') {
- self::$driver = new Lock\MemcacheLockDriver();
- } else {
+ $lock_driver = Config::get('system', 'lock_driver', 'default');
+
+ try {
+ switch ($lock_driver) {
+ case 'memcache':
+ case 'memcached':
+ case 'redis':
+ $cache_driver = CacheDriverFactory::create($lock_driver);
+ if ($cache_driver instanceof IMemoryCacheDriver) {
+ self::$driver = new Lock\CacheLockDriver($cache_driver);
+ }
+ break;
+
+ case 'database':
self::$driver = new Lock\DatabaseLockDriver();
+ break;
+
+ case 'semaphore':
+ self::$driver = new Lock\SemaphoreLockDriver();
+ break;
+
+ default:
+ self::useAutoDriver();
+ }
+ } catch (\Exception $exception) {
+ Logger::log('Driver \'' . $lock_driver . '\' failed - Fallback to \'useAutoDriver()\'');
+ 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
+ *
+ */
+ private static function useAutoDriver() {
+
+ // 1. Try to use Semaphores for - local - locking
+ if (function_exists('sem_get')) {
+ try {
+ self::$driver = new Lock\SemaphoreLockDriver();
+ return;
+ } catch (\Exception $exception) {
+ Logger::log('Using Semaphore driver for locking failed: ' . $exception->getMessage());
+ }
+ }
+
+ // 2. Try to use Cache Locking (don't use the DB-Cache Locking because it works different!)
+ $cache_driver = Config::get('system', 'cache_driver', 'database');
+ if ($cache_driver != 'database') {
+ try {
+ $lock_driver = CacheDriverFactory::create($cache_driver);
+ if ($lock_driver instanceof IMemoryCacheDriver) {
+ self::$driver = new Lock\CacheLockDriver($lock_driver);
}
+ return;
+ } catch (\Exception $exception) {
+ Logger::log('Using Cache driver for locking failed: ' . $exception->getMessage());
+ }
}
+
+ // 3. Use Database Locking as a Fallback
+ self::$driver = new Lock\DatabaseLockDriver();
}
/**
*
* @param string $key Name of the lock
* @param integer $timeout Seconds until we give up
+ * @param integer $ttl The Lock lifespan, must be one of the Cache constants
*
* @return boolean Was the lock successful?
*/
- public static function acquireLock($key, $timeout = 120)
+ public static function acquire($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
{
- return self::getDriver()->acquireLock($key, $timeout);
+ return self::getDriver()->acquireLock($key, $timeout, $ttl);
}
/**
* @brief Releases a lock if it was set by us
*
* @param string $key Name of the lock
- * @return mixed
+ * @return void
*/
- public static function releaseLock($key)
+ public static function release($key)
{
- return self::getDriver()->releaseLock($key);
+ self::getDriver()->releaseLock($key);
}
/**