From deb6b7a7c3d62a42e2f71a3adf7ba3689e741f5a Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Mon, 16 Nov 2020 19:46:20 +0000
Subject: [PATCH] Fallback to database lock if locking fails

---
 src/Factory/LockFactory.php |  4 ++--
 src/Model/Item.php          | 16 +++++++++++++---
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/Factory/LockFactory.php b/src/Factory/LockFactory.php
index afdf5213c6..4a45656de6 100644
--- a/src/Factory/LockFactory.php
+++ b/src/Factory/LockFactory.php
@@ -122,7 +122,7 @@ class LockFactory
 			try {
 				return new Lock\SemaphoreLock();
 			} catch (\Exception $exception) {
-				$this->logger->debug('Using Semaphore driver for locking failed.', ['exception' => $exception]);
+				$this->logger->warning('Using Semaphore driver for locking failed.', ['exception' => $exception]);
 			}
 		}
 
@@ -135,7 +135,7 @@ class LockFactory
 					return new Lock\CacheLock($cache);
 				}
 			} catch (\Exception $exception) {
-				$this->logger->debug('Using Cache driver for locking failed.', ['exception' => $exception]);
+				$this->logger->warning('Using Cache driver for locking failed.', ['exception' => $exception]);
 			}
 		}
 
diff --git a/src/Model/Item.php b/src/Model/Item.php
index d5f57cff75..aba3c37599 100644
--- a/src/Model/Item.php
+++ b/src/Model/Item.php
@@ -1905,10 +1905,16 @@ class Item
 			}
 		}
 
-		if (DI::lock()->acquire(self::LOCK_INSERT, 0)) {
+		$locked = DI::lock()->acquire(self::LOCK_INSERT, 0);
+
+		if ($locked || DBA::lock('item')) {
 			$condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'network' => $item['network']];
 			if (DBA::exists('item', $condition)) {
-				DI::lock()->release(self::LOCK_INSERT);
+				if ($locked) {
+					DI::lock()->release(self::LOCK_INSERT);
+				} else {
+					DBA::unlock();
+				}
 				Logger::notice('Item is already inserted - aborting', $condition);
 				return 0;
 			}
@@ -1917,7 +1923,11 @@ class Item
 
 			// When the item was successfully stored we fetch the ID of the item.
 			$current_post = DBA::lastInsertId();
-			DI::lock()->release(self::LOCK_INSERT);
+			if ($locked) {
+				DI::lock()->release(self::LOCK_INSERT);
+			} else {
+				DBA::unlock();
+			}
 		} else {
 			Logger::warning('Item lock had not been acquired');
 			$result = false;
-- 
2.39.5