From 9b7432781b1a3e33713b17b55ab94529f6f9de36 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Tue, 27 Aug 2019 21:01:11 +0200 Subject: [PATCH 1/4] Don't transmit content to already archived contacts --- src/Core/Worker.php | 4 ++-- src/Model/Contact.php | 45 ++++++++++++++++++++++++++++++++++++--- src/Protocol/Diaspora.php | 2 +- src/Worker/Delivery.php | 10 ++++++++- src/Worker/Notifier.php | 10 +++++++++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/src/Core/Worker.php b/src/Core/Worker.php index 1fd5378ab..f24df5252 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -1243,7 +1243,7 @@ class Worker $new_retrial = self::getNextRetrial($queue, $max_level); if ($new_retrial > $max_level) { - Logger::info('The task exceeded the maximum retry count', ['id' => $id, 'max_level' => $max_level, 'retrial' => $new_retrial]); + Logger::info('The task exceeded the maximum retry count', ['id' => $id, 'created' => $queue['created'], 'old_prio' => $queue['priority'], 'old_retrial' => $queue['retrial'], 'max_level' => $max_level, 'retrial' => $new_retrial]); return false; } @@ -1259,7 +1259,7 @@ class Worker $priority = PRIORITY_NEGLIGIBLE; } - Logger::info('Deferred task', ['id' => $id, 'retrial' => $new_retrial, 'next_execution' => $next, 'old_prio' => $queue['priority'], 'new_prio' => $priority]); + Logger::info('Deferred task', ['id' => $id, 'retrial' => $new_retrial, 'created' => $queue['created'], 'next_execution' => $next, 'old_prio' => $queue['priority'], 'new_prio' => $priority]); $stamp = (float)microtime(true); $fields = ['retrial' => $new_retrial, 'next_try' => $next, 'executed' => DBA::NULL_DATETIME, 'pid' => 0, 'priority' => $priority]; diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 6f9ee4cdb..75d820517 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -860,8 +860,8 @@ class Contact extends BaseObject * delete, though if the owner tries to unarchive them we'll start * the whole process over again. */ - DBA::update('contact', ['archive' => 1], ['id' => $contact['id']]); - DBA::update('contact', ['archive' => 1], ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]); + DBA::update('contact', ['archive' => true], ['id' => $contact['id']]); + DBA::update('contact', ['archive' => true], ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]); GContact::updateFromPublicContactURL($contact['url']); } } @@ -899,7 +899,7 @@ class Contact extends BaseObject // It's a miracle. Our dead contact has inexplicably come back to life. $fields = ['term-date' => DBA::NULL_DATETIME, 'archive' => false]; DBA::update('contact', $fields, ['id' => $contact['id']]); - DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($contact['url'])]); + DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]); GContact::updateFromPublicContactURL($contact['url']); if (!empty($contact['batch'])) { @@ -1556,6 +1556,45 @@ class Contact extends BaseObject return $contact_id; } + /** + * @brief Checks if the contact is archived + * + * @param int $cid contact id + * + * @return boolean Is the contact archived? + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + public static function isArchived($cid) + { + if ($cid == 0) { + return false; + } + + $archived = DBA::selectFirst('contact', ['archive', 'url'], ['id' => $cid]); + if (!DBA::isResult($archived)) { + return false; + } + + if ($archived['archive']) { + return true; + } + + $apcontact = APContact::getByURL($archived['url'], false); + if (empty($apcontact)) { + return false; + } + + if (!empty($apcontact['inbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['inbox']])) { + return true; + } + + if (!empty($apcontact['sharedinbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['sharedinbox']])) { + return true; + } + + return false; + } + /** * @brief Checks if the contact is blocked * diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 325debe7b..d578ba454 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -223,7 +223,7 @@ class Diaspora `fcontact`.`batch` AS `fbatch`, `fcontact`.`network` AS `fnetwork` FROM `participation` INNER JOIN `contact` ON `contact`.`id` = `participation`.`cid` INNER JOIN `fcontact` ON `fcontact`.`id` = `participation`.`fid` - WHERE `participation`.`iid` = ?", $thread); + WHERE `participation`.`iid` = ? AND NOT `contact`.`archive`", $thread); while ($contact = DBA::fetch($r)) { if (!empty($contact['fnetwork'])) { diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 7733d3f57..eb86f910d 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -33,7 +33,7 @@ class Delivery extends BaseObject public static function execute($cmd, $target_id, $contact_id) { - Logger::log('Invoked: ' . $cmd . ': ' . $target_id . ' to ' . $contact_id, Logger::DEBUG); + Logger::info('Invoked', ['cmd' => $cmd, 'target' => $target_id, 'contact' => $contact_id]); $top_level = false; $followup = false; @@ -96,6 +96,14 @@ class Delivery extends BaseObject return; } + if (!empty($contact_id) && Model\Contact::isArchived($contact_id)) { + Logger::info('Contact is archived', ['id' => $contact_id, 'cmd' => $cmd, 'item' => $target_item['id']]); + if (in_array($cmd, [Delivery::POST, Delivery::POKE])) { + Model\ItemDeliveryData::incrementQueueFailed($target_item['id']); + } + return; + } + // avoid race condition with deleting entries if ($items[0]['deleted']) { foreach ($items as $item) { diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 4efd3e912..20023792d 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -429,6 +429,11 @@ class Notifier if (DBA::isResult($r)) { foreach ($r as $rr) { + if (!empty($rr['id']) && Contact::isArchived($rr['id'])) { + Logger::info('Contact is archived', $rr); + continue; + } + if (self::isRemovalActivity($cmd, $owner, $rr['network'])) { Logger::log('Skipping dropping for ' . $rr['url'] . ' since the network supports account removal commands.', Logger::DEBUG); continue; @@ -463,6 +468,11 @@ class Notifier // delivery loop while ($contact = DBA::fetch($delivery_contacts_stmt)) { + if (!empty($contact['id']) && Contact::isArchived($contact['id'])) { + Logger::info('Contact is archived', $contact); + continue; + } + if (self::isRemovalActivity($cmd, $owner, $contact['network'])) { Logger::log('Skipping dropping for ' . $contact['url'] . ' since the network supports account removal commands.', Logger::DEBUG); continue; From cf170c9c0284bf438b1bec4c2f41ade49980b653 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 28 Aug 2019 06:44:37 +0200 Subject: [PATCH 2/4] Fixed count, added to-do --- src/Core/Worker.php | 2 +- src/Model/Contact.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Core/Worker.php b/src/Core/Worker.php index f24df5252..3da17d4a6 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -671,7 +671,7 @@ class Worker $waiting_processes = 0; // Now adding all processes with workerqueue entries $stamp = (float)microtime(true); - $jobs = DBA::p("SELECT COUNT(*) AS `entries`, `priority` FROM `workerqueue` WHERE NOT `done` AND `next_try` < ? GROUP BY `priority`", DateTimeFormat::utcNow()); + $jobs = DBA::p("SELECT COUNT(*) AS `entries`, `priority` FROM `workerqueue` WHERE NOT `done` GROUP BY `priority`"); self::$db_duration += (microtime(true) - $stamp); self::$db_duration_stat += (microtime(true) - $stamp); while ($entry = DBA::fetch($jobs)) { diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 75d820517..4d9260d3e 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1592,6 +1592,7 @@ class Contact extends BaseObject return true; } + /// @todo Add tests for Diaspora endpoints as well return false; } From 3c9834922cf4f0f8d5316b8bf8551df90f24baf2 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 28 Aug 2019 16:02:19 +0200 Subject: [PATCH 3/4] Check if the Diaspora endpoint is archived --- src/Model/Contact.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 4d9260d3e..0bde409fa 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1564,13 +1564,13 @@ class Contact extends BaseObject * @return boolean Is the contact archived? * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function isArchived($cid) + public static function isArchived(int $cid) { if ($cid == 0) { return false; } - $archived = DBA::selectFirst('contact', ['archive', 'url'], ['id' => $cid]); + $archived = DBA::selectFirst('contact', ['archive', 'url', 'batch'], ['id' => $cid]); if (!DBA::isResult($archived)) { return false; } @@ -1592,7 +1592,10 @@ class Contact extends BaseObject return true; } - /// @todo Add tests for Diaspora endpoints as well + if (!empty($archived['batch'])) { + return DBA::exists('contact', ['archive' => true, 'batch' => $archived['batch'], 'contact-type' => self::TYPE_RELAY]); + } + return false; } From 96b895bc3aa753261a3c648ee8cc545eb3196dcb Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 28 Aug 2019 16:54:49 +0200 Subject: [PATCH 4/4] Changed array name, fixed bug that prevented testing most Diaspora endpoints --- src/Model/Contact.php | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 0bde409fa..6887b9d0a 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1570,30 +1570,30 @@ class Contact extends BaseObject return false; } - $archived = DBA::selectFirst('contact', ['archive', 'url', 'batch'], ['id' => $cid]); - if (!DBA::isResult($archived)) { + $contact = DBA::selectFirst('contact', ['archive', 'url', 'batch'], ['id' => $cid]); + if (!DBA::isResult($contact)) { return false; } - if ($archived['archive']) { + if ($contact['archive']) { return true; } - $apcontact = APContact::getByURL($archived['url'], false); - if (empty($apcontact)) { - return false; + // Check status of ActivityPub endpoints + $apcontact = APContact::getByURL($contact['url'], false); + if (!empty($apcontact)) { + if (!empty($apcontact['inbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['inbox']])) { + return true; + } + + if (!empty($apcontact['sharedinbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['sharedinbox']])) { + return true; + } } - if (!empty($apcontact['inbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['inbox']])) { - return true; - } - - if (!empty($apcontact['sharedinbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['sharedinbox']])) { - return true; - } - - if (!empty($archived['batch'])) { - return DBA::exists('contact', ['archive' => true, 'batch' => $archived['batch'], 'contact-type' => self::TYPE_RELAY]); + // Check status of Diaspora endpoints + if (!empty($contact['batch'])) { + return DBA::exists('contact', ['archive' => true, 'batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY]); } return false;