From 58383f38d79a141e1af950a0d214b34e0bc3a978 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Oct 2020 13:09:35 +0000 Subject: [PATCH 1/2] Alternative item insert lock mechanism --- src/Model/Item.php | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Model/Item.php b/src/Model/Item.php index aea428cd7..d5958312f 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -71,6 +71,8 @@ class Item const PT_FETCHED = 75; const PT_PERSONAL_NOTE = 128; + const LOCK_ITEM = 'item-insert'; + // Field list that is used to display the items const DISPLAY_FIELDLIST = [ 'uid', 'id', 'parent', 'uri-id', 'uri', 'thr-parent', 'parent-uri', 'guid', 'network', 'gravity', @@ -1884,24 +1886,27 @@ class Item } } - DBA::lock('item'); + if (DI::lock()->acquire(self::LOCK_ITEM, 0)) { + $condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'network' => $item['network']]; + if (DBA::exists('item', $condition)) { + DI::lock()->release(self::LOCK_ITEM); + Logger::notice('Item is already inserted - aborting', $condition); + return 0; + } - $condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'network' => $item['network']]; - if (DBA::exists('item', $condition)) { - DBA::unlock(); - Logger::notice('Item is already inserted - aborting', $condition); - return 0; + $result = DBA::insert('item', $item); + + // When the item was successfully stored we fetch the ID of the item. + $current_post = DBA::lastInsertId(); + DI::lock()->release(self::LOCK_ITEM); + } else { + $result = false; + $current_post = 0; } - $ret = DBA::insert('item', $item); - - // When the item was successfully stored we fetch the ID of the item. - $current_post = DBA::lastInsertId(); - DBA::unlock(); - - if (!DBA::isResult($ret) || ($current_post == 0)) { + if (empty($current_post) || !DBA::isResult($result)) { // On failure store the data into a spool file so that the "SpoolPost" worker can try again later. - Logger::warning('Could not store item. it will be spooled', ['ret' => $ret, 'id' => $current_post]); + Logger::warning('Could not store item. it will be spooled', ['result' => $result, 'id' => $current_post]); self::spool($orig_item); return 0; } From da370c44baa17ccf75af8e393c738a91826ebc69 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 30 Oct 2020 17:26:12 +0000 Subject: [PATCH 2/2] Added lock for contacts, improved logging --- src/Model/Contact.php | 28 +++++++++++++++++----------- src/Model/Item.php | 9 +++++---- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 428bc3684..74a9619c2 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -91,6 +91,8 @@ class Contact * @} */ + const LOCK_INSERT = 'contact-insert'; + /** * Account types * @@ -1125,19 +1127,23 @@ class Contact $condition = ['nurl' => Strings::normaliseLink($data["url"]), 'uid' => $uid, 'deleted' => false]; // Before inserting we do check if the entry does exist now. - DBA::lock('contact'); - $contact = DBA::selectFirst('contact', ['id'], $condition, ['order' => ['id']]); - if (DBA::isResult($contact)) { - $contact_id = $contact['id']; - Logger::notice('Contact had been created (shortly) before', ['id' => $contact_id, 'url' => $url, 'uid' => $uid]); - } else { - DBA::insert('contact', $fields); - $contact_id = DBA::lastInsertId(); - if ($contact_id) { - Logger::info('Contact inserted', ['id' => $contact_id, 'url' => $url, 'uid' => $uid]); + if (DI::lock()->acquire(self::LOCK_INSERT, 0)) { + $contact = DBA::selectFirst('contact', ['id'], $condition, ['order' => ['id']]); + if (DBA::isResult($contact)) { + $contact_id = $contact['id']; + Logger::notice('Contact had been created (shortly) before', ['id' => $contact_id, 'url' => $url, 'uid' => $uid]); + } else { + DBA::insert('contact', $fields); + $contact_id = DBA::lastInsertId(); + if ($contact_id) { + Logger::info('Contact inserted', ['id' => $contact_id, 'url' => $url, 'uid' => $uid]); + } } + DI::lock()->release(self::LOCK_INSERT); + } else { + Logger::warning('Contact lock had not been acquired'); } - DBA::unlock(); + if (!$contact_id) { Logger::info('Contact was not inserted', ['url' => $url, 'uid' => $uid]); return 0; diff --git a/src/Model/Item.php b/src/Model/Item.php index 2be63d398..46d28ee82 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -71,7 +71,7 @@ class Item const PT_FETCHED = 75; const PT_PERSONAL_NOTE = 128; - const LOCK_ITEM = 'item-insert'; + const LOCK_INSERT = 'item-insert'; // Field list that is used to display the items const DISPLAY_FIELDLIST = [ @@ -1891,10 +1891,10 @@ class Item } } - if (DI::lock()->acquire(self::LOCK_ITEM, 0)) { + if (DI::lock()->acquire(self::LOCK_INSERT, 0)) { $condition = ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'network' => $item['network']]; if (DBA::exists('item', $condition)) { - DI::lock()->release(self::LOCK_ITEM); + DI::lock()->release(self::LOCK_INSERT); Logger::notice('Item is already inserted - aborting', $condition); return 0; } @@ -1903,8 +1903,9 @@ class Item // When the item was successfully stored we fetch the ID of the item. $current_post = DBA::lastInsertId(); - DI::lock()->release(self::LOCK_ITEM); + DI::lock()->release(self::LOCK_INSERT); } else { + Logger::warning('Item lock had not been acquired'); $result = false; $current_post = 0; }