]> git.mxchange.org Git - friendica.git/commitdiff
Restructure Lock to follow new paradigm
authorPhilipp <admin@philipp.info>
Sat, 23 Oct 2021 09:36:37 +0000 (11:36 +0200)
committerPhilipp <admin@philipp.info>
Tue, 26 Oct 2021 20:11:06 +0000 (22:11 +0200)
20 files changed:
src/Core/BaseLock.php [deleted file]
src/Core/Lock/CacheLock.php [deleted file]
src/Core/Lock/DatabaseLock.php [deleted file]
src/Core/Lock/Enum/Type.php [new file with mode: 0644]
src/Core/Lock/Factory/LockFactory.php [new file with mode: 0644]
src/Core/Lock/SemaphoreLock.php [deleted file]
src/Core/Lock/Type.php [deleted file]
src/Core/Lock/Type/BaseLock.php [new file with mode: 0644]
src/Core/Lock/Type/CacheLock.php [new file with mode: 0644]
src/Core/Lock/Type/DatabaseLock.php [new file with mode: 0644]
src/Core/Lock/Type/SemaphoreLock.php [new file with mode: 0644]
src/Factory/LockFactory.php [deleted file]
static/dependencies.config.php
tests/src/Core/Lock/APCuCacheLockTest.php
tests/src/Core/Lock/ArrayCacheLockTest.php
tests/src/Core/Lock/DatabaseLockDriverTest.php
tests/src/Core/Lock/MemcacheCacheLockTest.php
tests/src/Core/Lock/MemcachedCacheLockTest.php
tests/src/Core/Lock/RedisCacheLockTest.php
tests/src/Core/Lock/SemaphoreLockTest.php

diff --git a/src/Core/BaseLock.php b/src/Core/BaseLock.php
deleted file mode 100644 (file)
index 474fe98..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core;
-
-use Friendica\Core\Lock\ILock;
-
-/**
- * Basic class for Locking with common functions (local acquired locks, releaseAll, ..)
- */
-abstract class BaseLock implements ILock
-{
-       /**
-        * @var array The local acquired locks
-        */
-       protected $acquiredLocks = [];
-
-       /**
-        * Check if we've locally acquired a lock
-        *
-        * @param string key The Name of the lock
-        *
-        * @return bool      Returns true if the lock is set
-        */
-       protected function hasAcquiredLock($key)
-       {
-               return isset($this->acquireLock[$key]) && $this->acquiredLocks[$key] === true;
-       }
-
-       /**
-        * Mark a locally acquired lock
-        *
-        * @param string $key The Name of the lock
-        */
-       protected function markAcquire($key)
-       {
-               $this->acquiredLocks[$key] = true;
-       }
-
-       /**
-        * Mark a release of a locally acquired lock
-        *
-        * @param string $key The Name of the lock
-        */
-       protected function markRelease($key)
-       {
-               unset($this->acquiredLocks[$key]);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function releaseAll($override = false)
-       {
-               $return = true;
-
-               foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
-                       if (!$this->release($acquiredLock, $override)) {
-                               $return = false;
-                       }
-               }
-
-               return $return;
-       }
-}
diff --git a/src/Core/Lock/CacheLock.php b/src/Core/Lock/CacheLock.php
deleted file mode 100644 (file)
index 20705e0..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\BaseLock;
-use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Core\Cache\IMemoryCache;
-
-class CacheLock extends BaseLock
-{
-       /**
-        * @var string The static prefix of all locks inside the cache
-        */
-       const CACHE_PREFIX = 'lock:';
-
-       /**
-        * @var \Friendica\Core\Cache\ICache;
-        */
-       private $cache;
-
-       /**
-        * CacheLock constructor.
-        *
-        * @param IMemoryCache $cache The CacheDriver for this type of lock
-        */
-       public function __construct(IMemoryCache $cache)
-       {
-               $this->cache = $cache;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
-       {
-               $got_lock = false;
-               $start    = time();
-
-               $cachekey = self::getLockKey($key);
-
-               do {
-                       $lock = $this->cache->get($cachekey);
-                       // When we do want to lock something that was already locked by us.
-                       if ((int)$lock == getmypid()) {
-                               $got_lock = true;
-                       }
-
-                       // When we do want to lock something new
-                       if (is_null($lock)) {
-                               // At first initialize it with "0"
-                               $this->cache->add($cachekey, 0);
-                               // Now the value has to be "0" because otherwise the key was used by another process meanwhile
-                               if ($this->cache->compareSet($cachekey, 0, getmypid(), $ttl)) {
-                                       $got_lock = true;
-                                       $this->markAcquire($key);
-                               }
-                       }
-
-                       if (!$got_lock && ($timeout > 0)) {
-                               usleep(rand(10000, 200000));
-                       }
-               } while (!$got_lock && ((time() - $start) < $timeout));
-
-               return $got_lock;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function release($key, $override = false)
-       {
-               $cachekey = self::getLockKey($key);
-
-               if ($override) {
-                       $return = $this->cache->delete($cachekey);
-               } else {
-                       $return = $this->cache->compareDelete($cachekey, getmypid());
-               }
-               $this->markRelease($key);
-
-               return $return;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function isLocked($key)
-       {
-               $cachekey = self::getLockKey($key);
-               $lock     = $this->cache->get($cachekey);
-               return isset($lock) && ($lock !== false);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName()
-       {
-               return $this->cache->getName();
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getLocks(string $prefix = '')
-       {
-               $locks = $this->cache->getAllKeys(self::CACHE_PREFIX . $prefix);
-
-               array_walk($locks, function (&$lock, $key) {
-                       $lock = substr($lock, strlen(self::CACHE_PREFIX));
-               });
-
-               return $locks;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function releaseAll($override = false)
-       {
-               $success = parent::releaseAll($override);
-
-               $locks = $this->getLocks();
-
-               foreach ($locks as $lock) {
-                       if (!$this->release($lock, $override)) {
-                               $success = false;
-                       }
-               }
-
-               return $success;
-       }
-
-       /**
-        * @param string $key The original key
-        *
-        * @return string        The cache key used for the cache
-        */
-       private static function getLockKey($key)
-       {
-               return self::CACHE_PREFIX . $key;
-       }
-}
diff --git a/src/Core/Lock/DatabaseLock.php b/src/Core/Lock/DatabaseLock.php
deleted file mode 100644 (file)
index 14e78f6..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\BaseLock;
-use Friendica\Core\Cache\Enum\Duration;
-use Friendica\Database\Database;
-use Friendica\Util\DateTimeFormat;
-
-/**
- * Locking driver that stores the locks in the database
- */
-class DatabaseLock extends BaseLock
-{
-       /**
-        * The current ID of the process
-        *
-        * @var int
-        */
-       private $pid;
-
-       /**
-        * @var Database The database connection of Friendica
-        */
-       private $dba;
-
-       /**
-        * @param null|int $pid The Id of the current process (null means determine automatically)
-        */
-       public function __construct(Database $dba, $pid = null)
-       {
-               $this->dba = $dba;
-               $this->pid = isset($pid) ? $pid : getmypid();
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
-       {
-               $got_lock = false;
-               $start    = time();
-
-               do {
-                       $this->dba->lock('locks');
-                       $lock = $this->dba->selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
-
-                       if ($this->dba->isResult($lock)) {
-                               if ($lock['locked']) {
-                                       // We want to lock something that was already locked by us? So we got the lock.
-                                       if ($lock['pid'] == $this->pid) {
-                                               $got_lock = true;
-                                       }
-                               }
-                               if (!$lock['locked']) {
-                                       $this->dba->update('locks', ['locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
-                                       $got_lock = true;
-                               }
-                       } else {
-                               $this->dba->insert('locks', ['name' => $key, 'locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
-                               $got_lock = true;
-                               $this->markAcquire($key);
-                       }
-
-                       $this->dba->unlock();
-
-                       if (!$got_lock && ($timeout > 0)) {
-                               usleep(rand(100000, 2000000));
-                       }
-               } while (!$got_lock && ((time() - $start) < $timeout));
-
-               return $got_lock;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function release($key, $override = false)
-       {
-               if ($override) {
-                       $where = ['name' => $key];
-               } else {
-                       $where = ['name' => $key, 'pid' => $this->pid];
-               }
-
-               if ($this->dba->exists('locks', $where)) {
-                       $return = $this->dba->delete('locks', $where);
-               } else {
-                       $return = false;
-               }
-
-               $this->markRelease($key);
-
-               return $return;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function releaseAll($override = false)
-       {
-               $success = parent::releaseAll($override);
-
-               if ($override) {
-                       $where = ['1 = 1'];
-               } else {
-                       $where = ['pid' => $this->pid];
-               }
-               $return = $this->dba->delete('locks', $where);
-
-               $this->acquiredLocks = [];
-
-               return $return && $success;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function isLocked($key)
-       {
-               $lock = $this->dba->selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
-
-               if ($this->dba->isResult($lock)) {
-                       return $lock['locked'] !== false;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName()
-       {
-               return Type::DATABASE;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getLocks(string $prefix = '')
-       {
-               if (empty($prefix)) {
-                       $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
-               } else {
-                       $where = ['`expires` >= ? AND `name` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
-               }
-
-               $stmt = $this->dba->select('locks', ['name'], $where);
-
-               $keys = [];
-               while ($key = $this->dba->fetch($stmt)) {
-                       array_push($keys, $key['name']);
-               }
-               $this->dba->close($stmt);
-
-               return $keys;
-       }
-}
diff --git a/src/Core/Lock/Enum/Type.php b/src/Core/Lock/Enum/Type.php
new file mode 100644 (file)
index 0000000..1ad1ef7
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Enum;
+
+use Friendica\Core\Cache\Enum\Type as CacheType;
+
+/**
+ * Enumeration for lock types
+ *
+ * There's no "Cache" lock type, because the type depends on the concrete, used cache
+ */
+abstract class Type
+{
+       const DATABASE  = CacheType::DATABASE;
+       const SEMAPHORE = 'semaphore';
+}
diff --git a/src/Core/Lock/Factory/LockFactory.php b/src/Core/Lock/Factory/LockFactory.php
new file mode 100644 (file)
index 0000000..124ed2f
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Factory;
+
+use Friendica\Core\Cache\Factory\CacheFactory;
+use Friendica\Core\Cache\IMemoryCache;
+use Friendica\Core\Cache\Enum\Type;
+use Friendica\Core\Config\IConfig;
+use Friendica\Core\Lock;
+use Friendica\Database\Database;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class LockFactory
+ *
+ * @package Friendica\Core\Cache
+ *
+ * A basic class to generate a LockDriver
+ */
+class LockFactory
+{
+       /**
+        * @var string The default driver for caching
+        */
+       const DEFAULT_DRIVER = 'default';
+
+       /**
+        * @var IConfig The configuration to read parameters out of the config
+        */
+       private $config;
+
+       /**
+        * @var Database The database connection in case that the cache is used the dba connection
+        */
+       private $dba;
+
+       /**
+        * @var CacheFactory The memory cache driver in case we use it
+        */
+       private $cacheFactory;
+
+       /**
+        * @var LoggerInterface The Friendica Logger
+        */
+       private $logger;
+
+       public function __construct(CacheFactory $cacheFactory, IConfig $config, Database $dba, LoggerInterface $logger)
+       {
+               $this->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 Type::MEMCACHE:
+                               case Type::MEMCACHED:
+                               case Type::REDIS:
+                               case Type::APCU:
+                                       $cache = $this->cacheFactory->create($lock_type);
+                                       if ($cache instanceof IMemoryCache) {
+                                               return new Lock\Type\CacheLock($cache);
+                                       } else {
+                                               throw new \Exception(sprintf('Incompatible cache driver \'%s\' for lock used', $lock_type));
+                                       }
+                                       break;
+
+                               case 'database':
+                                       return new Lock\Type\DatabaseLock($this->dba);
+                                       break;
+
+                               case 'semaphore':
+                                       return new Lock\Type\SemaphoreLock();
+                                       break;
+
+                               default:
+                                       return self::useAutoDriver();
+                       }
+               } catch (\Exception $exception) {
+                       $this->logger->alert('Driver \'' . $lock_type . '\' failed - Fallback to \'useAutoDriver()\'', ['exception' => $exception]);
+                       return self::useAutoDriver();
+               }
+       }
+
+       /**
+        * 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\Type\SemaphoreLock();
+                       } catch (\Exception $exception) {
+                               $this->logger->warning('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 != Type::DATABASE) {
+                       try {
+                               $cache = $this->cacheFactory->create($cache_type);
+                               if ($cache instanceof IMemoryCache) {
+                                       return new Lock\Type\CacheLock($cache);
+                               }
+                       } catch (\Exception $exception) {
+                               $this->logger->warning('Using Cache driver for locking failed.', ['exception' => $exception]);
+                       }
+               }
+
+               // 3. Use Database Locking as a Fallback
+               return new Lock\Type\DatabaseLock($this->dba);
+       }
+}
diff --git a/src/Core/Lock/SemaphoreLock.php b/src/Core/Lock/SemaphoreLock.php
deleted file mode 100644 (file)
index fa5cf5e..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\BaseLock;
-use Friendica\Core\Cache\Enum\Duration;
-
-class SemaphoreLock extends BaseLock
-{
-       private static $semaphore = [];
-
-       public function __construct()
-       {
-               if (!function_exists('sem_get')) {
-                       throw new \Exception('Semaphore lock not supported');
-               }
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       private static function semaphoreKey($key)
-       {
-               $success = true;
-
-               $temp = get_temppath();
-
-               $file = $temp . '/' . $key . '.sem';
-
-               if (!file_exists($file)) {
-                       $success = !empty(file_put_contents($file, $key));
-               }
-
-               return $success ? ftok($file, 'f') : false;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
-       {
-               self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
-               if (!empty(self::$semaphore[$key])) {
-                       if ((bool)sem_acquire(self::$semaphore[$key], ($timeout === 0))) {
-                               $this->markAcquire($key);
-                               return true;
-                       }
-               }
-
-               return false;
-       }
-
-       /**
-        * (@inheritdoc)
-        *
-        * @param bool $override not necessary parameter for semaphore locks since the lock lives as long as the execution
-        *                       of the using function
-        */
-       public function release($key, $override = false)
-       {
-               $success = false;
-
-               if (!empty(self::$semaphore[$key])) {
-                       try {
-                               $success = @sem_release(self::$semaphore[$key]);
-                               unset(self::$semaphore[$key]);
-                               $this->markRelease($key);
-                       } catch (\Exception $exception) {
-                               $success = false;
-                       }
-               }
-
-               return $success;
-       }
-
-       /**
-        * (@inheritdoc)
-        */
-       public function isLocked($key)
-       {
-               return isset(self::$semaphore[$key]);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getName()
-       {
-               return Type::SEMAPHORE;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getLocks(string $prefix = '')
-       {
-               // We can just return our own semaphore keys, since we don't know
-               // the state of other semaphores, even if the .sem files exists
-               $keys = array_keys(self::$semaphore);
-
-               if (empty($prefix)) {
-                       return $keys;
-               } else {
-                       $result = [];
-
-                       foreach ($keys as $key) {
-                               if (strpos($key, $prefix) === 0) {
-                                       array_push($result, $key);
-                               }
-                       }
-
-                       return $result;
-               }
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function releaseAll($override = false)
-       {
-               // Semaphores are just alive during a run, so there is no need to release
-               // You can just release your own locks
-               return parent::releaseAll($override);
-       }
-}
diff --git a/src/Core/Lock/Type.php b/src/Core/Lock/Type.php
deleted file mode 100644 (file)
index 769bad1..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Lock;
-
-use Friendica\Core\Cache\Enum\Type as CacheType;
-
-/**
- * Enumeration for lock types
- *
- * There's no "Cache" lock type, because the type depends on the concrete, used cache
- */
-abstract class Type
-{
-       const DATABASE  = CacheType::DATABASE;
-       const SEMAPHORE = 'semaphore';
-}
diff --git a/src/Core/Lock/Type/BaseLock.php b/src/Core/Lock/Type/BaseLock.php
new file mode 100644 (file)
index 0000000..518475b
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Type;
+
+use Friendica\Core\Lock\ILock;
+
+/**
+ * Basic class for Locking with common functions (local acquired locks, releaseAll, ..)
+ */
+abstract class BaseLock implements ILock
+{
+       /**
+        * @var array The local acquired locks
+        */
+       protected $acquiredLocks = [];
+
+       /**
+        * Check if we've locally acquired a lock
+        *
+        * @param string key The Name of the lock
+        *
+        * @return bool      Returns true if the lock is set
+        */
+       protected function hasAcquiredLock($key)
+       {
+               return isset($this->acquireLock[$key]) && $this->acquiredLocks[$key] === true;
+       }
+
+       /**
+        * Mark a locally acquired lock
+        *
+        * @param string $key The Name of the lock
+        */
+       protected function markAcquire($key)
+       {
+               $this->acquiredLocks[$key] = true;
+       }
+
+       /**
+        * Mark a release of a locally acquired lock
+        *
+        * @param string $key The Name of the lock
+        */
+       protected function markRelease($key)
+       {
+               unset($this->acquiredLocks[$key]);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function releaseAll($override = false)
+       {
+               $return = true;
+
+               foreach ($this->acquiredLocks as $acquiredLock => $hasLock) {
+                       if (!$this->release($acquiredLock, $override)) {
+                               $return = false;
+                       }
+               }
+
+               return $return;
+       }
+}
diff --git a/src/Core/Lock/Type/CacheLock.php b/src/Core/Lock/Type/CacheLock.php
new file mode 100644 (file)
index 0000000..8a85f07
--- /dev/null
@@ -0,0 +1,161 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Type;
+
+use Friendica\Core\Cache\Enum\Duration;
+use Friendica\Core\Cache\IMemoryCache;
+
+class CacheLock extends BaseLock
+{
+       /**
+        * @var string The static prefix of all locks inside the cache
+        */
+       const CACHE_PREFIX = 'lock:';
+
+       /**
+        * @var \Friendica\Core\Cache\ICache;
+        */
+       private $cache;
+
+       /**
+        * CacheLock constructor.
+        *
+        * @param IMemoryCache $cache The CacheDriver for this type of lock
+        */
+       public function __construct(IMemoryCache $cache)
+       {
+               $this->cache = $cache;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
+       {
+               $got_lock = false;
+               $start    = time();
+
+               $cachekey = self::getLockKey($key);
+
+               do {
+                       $lock = $this->cache->get($cachekey);
+                       // When we do want to lock something that was already locked by us.
+                       if ((int)$lock == getmypid()) {
+                               $got_lock = true;
+                       }
+
+                       // When we do want to lock something new
+                       if (is_null($lock)) {
+                               // At first initialize it with "0"
+                               $this->cache->add($cachekey, 0);
+                               // Now the value has to be "0" because otherwise the key was used by another process meanwhile
+                               if ($this->cache->compareSet($cachekey, 0, getmypid(), $ttl)) {
+                                       $got_lock = true;
+                                       $this->markAcquire($key);
+                               }
+                       }
+
+                       if (!$got_lock && ($timeout > 0)) {
+                               usleep(rand(10000, 200000));
+                       }
+               } while (!$got_lock && ((time() - $start) < $timeout));
+
+               return $got_lock;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function release($key, $override = false)
+       {
+               $cachekey = self::getLockKey($key);
+
+               if ($override) {
+                       $return = $this->cache->delete($cachekey);
+               } else {
+                       $return = $this->cache->compareDelete($cachekey, getmypid());
+               }
+               $this->markRelease($key);
+
+               return $return;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function isLocked($key)
+       {
+               $cachekey = self::getLockKey($key);
+               $lock     = $this->cache->get($cachekey);
+               return isset($lock) && ($lock !== false);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getName()
+       {
+               return $this->cache->getName();
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getLocks(string $prefix = '')
+       {
+               $locks = $this->cache->getAllKeys(self::CACHE_PREFIX . $prefix);
+
+               array_walk($locks, function (&$lock, $key) {
+                       $lock = substr($lock, strlen(self::CACHE_PREFIX));
+               });
+
+               return $locks;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function releaseAll($override = false)
+       {
+               $success = parent::releaseAll($override);
+
+               $locks = $this->getLocks();
+
+               foreach ($locks as $lock) {
+                       if (!$this->release($lock, $override)) {
+                               $success = false;
+                       }
+               }
+
+               return $success;
+       }
+
+       /**
+        * @param string $key The original key
+        *
+        * @return string        The cache key used for the cache
+        */
+       private static function getLockKey($key)
+       {
+               return self::CACHE_PREFIX . $key;
+       }
+}
diff --git a/src/Core/Lock/Type/DatabaseLock.php b/src/Core/Lock/Type/DatabaseLock.php
new file mode 100644 (file)
index 0000000..de44e2e
--- /dev/null
@@ -0,0 +1,178 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Type;
+
+use Friendica\Core\Cache\Enum\Duration;
+use Friendica\Core\Lock\Enum\Type;
+use Friendica\Database\Database;
+use Friendica\Util\DateTimeFormat;
+
+/**
+ * Locking driver that stores the locks in the database
+ */
+class DatabaseLock extends BaseLock
+{
+       /**
+        * The current ID of the process
+        *
+        * @var int
+        */
+       private $pid;
+
+       /**
+        * @var Database The database connection of Friendica
+        */
+       private $dba;
+
+       /**
+        * @param null|int $pid The Id of the current process (null means determine automatically)
+        */
+       public function __construct(Database $dba, $pid = null)
+       {
+               $this->dba = $dba;
+               $this->pid = isset($pid) ? $pid : getmypid();
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
+       {
+               $got_lock = false;
+               $start    = time();
+
+               do {
+                       $this->dba->lock('locks');
+                       $lock = $this->dba->selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+
+                       if ($this->dba->isResult($lock)) {
+                               if ($lock['locked']) {
+                                       // We want to lock something that was already locked by us? So we got the lock.
+                                       if ($lock['pid'] == $this->pid) {
+                                               $got_lock = true;
+                                       }
+                               }
+                               if (!$lock['locked']) {
+                                       $this->dba->update('locks', ['locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
+                                       $got_lock = true;
+                               }
+                       } else {
+                               $this->dba->insert('locks', ['name' => $key, 'locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
+                               $got_lock = true;
+                               $this->markAcquire($key);
+                       }
+
+                       $this->dba->unlock();
+
+                       if (!$got_lock && ($timeout > 0)) {
+                               usleep(rand(100000, 2000000));
+                       }
+               } while (!$got_lock && ((time() - $start) < $timeout));
+
+               return $got_lock;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function release($key, $override = false)
+       {
+               if ($override) {
+                       $where = ['name' => $key];
+               } else {
+                       $where = ['name' => $key, 'pid' => $this->pid];
+               }
+
+               if ($this->dba->exists('locks', $where)) {
+                       $return = $this->dba->delete('locks', $where);
+               } else {
+                       $return = false;
+               }
+
+               $this->markRelease($key);
+
+               return $return;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function releaseAll($override = false)
+       {
+               $success = parent::releaseAll($override);
+
+               if ($override) {
+                       $where = ['1 = 1'];
+               } else {
+                       $where = ['pid' => $this->pid];
+               }
+               $return = $this->dba->delete('locks', $where);
+
+               $this->acquiredLocks = [];
+
+               return $return && $success;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function isLocked($key)
+       {
+               $lock = $this->dba->selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+
+               if ($this->dba->isResult($lock)) {
+                       return $lock['locked'] !== false;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getName()
+       {
+               return Type::DATABASE;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getLocks(string $prefix = '')
+       {
+               if (empty($prefix)) {
+                       $where = ['`expires` >= ?', DateTimeFormat::utcNow()];
+               } else {
+                       $where = ['`expires` >= ? AND `name` LIKE CONCAT(?, \'%\')', DateTimeFormat::utcNow(), $prefix];
+               }
+
+               $stmt = $this->dba->select('locks', ['name'], $where);
+
+               $keys = [];
+               while ($key = $this->dba->fetch($stmt)) {
+                       array_push($keys, $key['name']);
+               }
+               $this->dba->close($stmt);
+
+               return $keys;
+       }
+}
diff --git a/src/Core/Lock/Type/SemaphoreLock.php b/src/Core/Lock/Type/SemaphoreLock.php
new file mode 100644 (file)
index 0000000..4393e45
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Lock\Type;
+
+use Friendica\Core\Cache\Enum\Duration;
+use Friendica\Core\Lock\Enum\Type;
+use function get_temppath;
+
+class SemaphoreLock extends BaseLock
+{
+       private static $semaphore = [];
+
+       public function __construct()
+       {
+               if (!function_exists('sem_get')) {
+                       throw new \Exception('Semaphore lock not supported');
+               }
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       private static function semaphoreKey($key)
+       {
+               $success = true;
+
+               $temp = get_temppath();
+
+               $file = $temp . '/' . $key . '.sem';
+
+               if (!file_exists($file)) {
+                       $success = !empty(file_put_contents($file, $key));
+               }
+
+               return $success ? ftok($file, 'f') : false;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
+       {
+               self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
+               if (!empty(self::$semaphore[$key])) {
+                       if ((bool)sem_acquire(self::$semaphore[$key], ($timeout === 0))) {
+                               $this->markAcquire($key);
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * (@inheritdoc)
+        *
+        * @param bool $override not necessary parameter for semaphore locks since the lock lives as long as the execution
+        *                       of the using function
+        */
+       public function release($key, $override = false)
+       {
+               $success = false;
+
+               if (!empty(self::$semaphore[$key])) {
+                       try {
+                               $success = @sem_release(self::$semaphore[$key]);
+                               unset(self::$semaphore[$key]);
+                               $this->markRelease($key);
+                       } catch (\Exception $exception) {
+                               $success = false;
+                       }
+               }
+
+               return $success;
+       }
+
+       /**
+        * (@inheritdoc)
+        */
+       public function isLocked($key)
+       {
+               return isset(self::$semaphore[$key]);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getName()
+       {
+               return Type::SEMAPHORE;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getLocks(string $prefix = '')
+       {
+               // We can just return our own semaphore keys, since we don't know
+               // the state of other semaphores, even if the .sem files exists
+               $keys = array_keys(self::$semaphore);
+
+               if (empty($prefix)) {
+                       return $keys;
+               } else {
+                       $result = [];
+
+                       foreach ($keys as $key) {
+                               if (strpos($key, $prefix) === 0) {
+                                       array_push($result, $key);
+                               }
+                       }
+
+                       return $result;
+               }
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function releaseAll($override = false)
+       {
+               // Semaphores are just alive during a run, so there is no need to release
+               // You can just release your own locks
+               return parent::releaseAll($override);
+       }
+}
diff --git a/src/Factory/LockFactory.php b/src/Factory/LockFactory.php
deleted file mode 100644 (file)
index 2a54910..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Factory;
-
-use Friendica\Core\Cache\Factory\CacheFactory;
-use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Cache\Enum\Type;
-use Friendica\Core\Config\IConfig;
-use Friendica\Core\Lock;
-use Friendica\Database\Database;
-use Psr\Log\LoggerInterface;
-
-/**
- * Class LockFactory
- *
- * @package Friendica\Core\Cache
- *
- * A basic class to generate a LockDriver
- */
-class LockFactory
-{
-       /**
-        * @var string The default driver for caching
-        */
-       const DEFAULT_DRIVER = 'default';
-
-       /**
-        * @var IConfig The configuration to read parameters out of the config
-        */
-       private $config;
-
-       /**
-        * @var Database The database connection in case that the cache is used the dba connection
-        */
-       private $dba;
-
-       /**
-        * @var CacheFactory The memory cache driver in case we use it
-        */
-       private $cacheFactory;
-
-       /**
-        * @var LoggerInterface The Friendica Logger
-        */
-       private $logger;
-
-       public function __construct(CacheFactory $cacheFactory, IConfig $config, Database $dba, LoggerInterface $logger)
-       {
-               $this->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 Type::MEMCACHE:
-                               case Type::MEMCACHED:
-                               case Type::REDIS:
-                               case 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();
-               }
-       }
-
-       /**
-        * 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->warning('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 != Type::DATABASE) {
-                       try {
-                               $cache = $this->cacheFactory->create($cache_type);
-                               if ($cache instanceof IMemoryCache) {
-                                       return new Lock\CacheLock($cache);
-                               }
-                       } catch (\Exception $exception) {
-                               $this->logger->warning('Using Cache driver for locking failed.', ['exception' => $exception]);
-                       }
-               }
-
-               // 3. Use Database Locking as a Fallback
-               return new Lock\DatabaseLock($this->dba);
-       }
-}
index fe063c0463b049d310bcd601e95da1f9567fa17e..48ed997f337a62d095e58065a2d2f741e4a38c60 100644 (file)
@@ -39,7 +39,7 @@ use Friendica\Core\Cache;
 use Friendica\Core\Config;
 use Friendica\Core\PConfig;
 use Friendica\Core\L10n;
-use Friendica\Core\Lock\ILock;
+use Friendica\Core\Lock;
 use Friendica\Core\Process;
 use Friendica\Core\Session\ISession;
 use Friendica\Core\StorageManager;
@@ -101,7 +101,7 @@ return [
                        ['create', [], Dice::CHAIN_CALL],
                ],
        ],
-       \Friendica\Core\PConfig\IPConfig::class => [
+       PConfig\IPConfig::class => [
                'instanceOf' => PConfig\Factory\PConfigFactory::class,
                'call'       => [
                        ['create', [], Dice::CHAIN_CALL],
@@ -170,8 +170,8 @@ return [
                        ['create', [], Dice::CHAIN_CALL],
                ],
        ],
-       ILock::class                    => [
-               'instanceOf' => Factory\LockFactory::class,
+       Lock\ILock::class                    => [
+               'instanceOf' => Lock\Factory\LockFactory::class,
                'call'       => [
                        ['create', [], Dice::CHAIN_CALL],
                ],
index 750748975a76cb3bf824b7adf50d693bf831371c..3f13000e03b8252e3f3d9fa6779b5a9de7a18e17 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\Test\src\Core\Lock;
 
 use Friendica\Core\Cache\Type\APCuCache;
-use Friendica\Core\Lock\CacheLock;
+use Friendica\Core\Lock\Type\CacheLock;
 
 /**
  * @group APCU
@@ -40,6 +40,6 @@ class APCuCacheLockTest extends LockTest
 
        protected function getInstance()
        {
-               return new CacheLock(new APCuCache('localhost'));
+               return new \Friendica\Core\Lock\Type\CacheLock(new APCuCache('localhost'));
        }
 }
index 93c2c20526bc344853ca09fb2697c2b3b855a376..4f6bf3fe917c627ad3ec67ead84e3a028e4cc1b1 100644 (file)
 namespace Friendica\Test\src\Core\Lock;
 
 use Friendica\Core\Cache\Type\ArrayCache;
-use Friendica\Core\Lock\CacheLock;
+use Friendica\Core\Lock\Type\CacheLock;
 
 class ArrayCacheLockTest extends LockTest
 {
        protected function getInstance()
        {
-               return new CacheLock(new ArrayCache('localhost'));
+               return new \Friendica\Core\Lock\Type\CacheLock(new ArrayCache('localhost'));
        }
 
        /**
index 86209d5c7d70c0bf23e292fbc3be684b9b55d850..e08a0d7ca82be623b56b44428f1e8bb296ca27c3 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Core\Lock;
 
-use Friendica\Core\Lock\DatabaseLock;
+use Friendica\Core\Lock\Type\DatabaseLock;
 use Friendica\Core\Config\Factory\ConfigFactory;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
index efb27dcabab60b28846f65e38c2193b121c40ce0..a3068b6a53b8c31ffbb4440526f0388c93ab1645 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Core\Lock;
 use Exception;
 use Friendica\Core\Cache\Type\MemcacheCache;
 use Friendica\Core\Config\IConfig;
-use Friendica\Core\Lock\CacheLock;
+use Friendica\Core\Lock\Type\CacheLock;
 use Mockery;
 
 /**
@@ -53,7 +53,7 @@ class MemcacheCacheLockTest extends LockTest
 
                try {
                        $cache = new MemcacheCache($host, $configMock);
-                       $lock = new CacheLock($cache);
+                       $lock = new \Friendica\Core\Lock\Type\CacheLock($cache);
                } catch (Exception $e) {
                        static::markTestSkipped('Memcache is not available');
                }
index f729364847ec6ff961b0b15ea61a06ea6dc184e8..26cc16f22b8601433f79285de7910ddf0afc2ca0 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Core\Lock;
 use Exception;
 use Friendica\Core\Cache\Type\MemcachedCache;
 use Friendica\Core\Config\IConfig;
-use Friendica\Core\Lock\CacheLock;
+use Friendica\Core\Lock\Type\CacheLock;
 use Mockery;
 use Psr\Log\NullLogger;
 
index 6fdbd1eeb9953451055c0f03b9fcb59f67de3bd9..fba68b197c1cab4409f2ab80b0005e10e693f5fd 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Core\Lock;
 use Exception;
 use Friendica\Core\Cache\Type\RedisCache;
 use Friendica\Core\Config\IConfig;
-use Friendica\Core\Lock\CacheLock;
+use Friendica\Core\Lock\Type\CacheLock;
 use Mockery;
 
 /**
@@ -62,7 +62,7 @@ class RedisCacheLockTest extends LockTest
 
                try {
                        $cache = new RedisCache($host, $configMock);
-                       $lock = new CacheLock($cache);
+                       $lock = new \Friendica\Core\Lock\Type\CacheLock($cache);
                } catch (Exception $e) {
                        static::markTestSkipped('Redis is not available. Error: ' . $e->getMessage());
                }
index 89a3ec633cb8adfb04c4346d97b274b597736d2f..59b110a333aafe3a8c78f1915ed5c2e2d86d358b 100644 (file)
@@ -25,7 +25,7 @@ use Dice\Dice;
 use Friendica\App;
 use Friendica\Core\Config\IConfig;
 use Friendica\Core\Config\Type\JitConfig;
-use Friendica\Core\Lock\SemaphoreLock;
+use Friendica\Core\Lock\Type\SemaphoreLock;
 use Friendica\DI;
 use Mockery;
 use Mockery\MockInterface;
@@ -56,7 +56,7 @@ class SemaphoreLockTest extends LockTest
 
        protected function getInstance()
        {
-               return new SemaphoreLock();
+               return new \Friendica\Core\Lock\Type\SemaphoreLock();
        }
 
        /**