From 9f96f3ef347e44851a265b1d99e5bb6cf2f4514b Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 4 Dec 2020 05:53:11 +0000 Subject: [PATCH] Moved updating personal contacts to updatecontact --- src/Model/Contact.php | 40 ++++++++------ src/Module/Contact.php | 4 +- src/Worker/Cron.php | 2 +- src/Worker/OnePoll.php | 2 +- src/Worker/PollContacts.php | 3 +- ...ePublicContacts.php => UpdateContacts.php} | 54 ++++++++++--------- static/defaults.config.php | 4 ++ 7 files changed, 62 insertions(+), 47 deletions(-) rename src/Worker/{UpdatePublicContacts.php => UpdateContacts.php} (63%) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 99e34abd20..4c173c1be3 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1722,31 +1722,38 @@ class Contact } // Search for duplicated contacts and get rid of them - if (self::removeDuplicates(Strings::normaliseLink($url), $uid) || ($uid != 0)) { + if (self::removeDuplicates(Strings::normaliseLink($url), $uid)) { return; } - // Archive or unarchive the contact. We only need to do this for the public contact. - // The archive/unarchive function will update the personal contacts by themselves. + // Archive or unarchive the contact. $contact = DBA::selectFirst('contact', [], ['id' => $id]); if (!DBA::isResult($contact)) { Logger::info('Couldn\'t select contact for archival.', ['id' => $id]); return; } - if (!empty($fields['success_update'])) { - self::unmarkForArchival($contact); - } elseif (!empty($fields['failure_update'])) { - self::markForArchival($contact); + if (isset($fields['failed'])) { + if ($fields['failed']) { + self::markForArchival($contact); + } else { + self::unmarkForArchival($contact); + } } - $condition = ['self' => false, 'nurl' => Strings::normaliseLink($url), 'network' => Protocol::FEDERATED]; + if ($contact['uid'] != 0) { + return; + } - // These contacts are sharing with us, we don't poll them. - // This means that we don't set the update fields in "OnePoll.php". - $condition['rel'] = self::SHARING; + // Update contact data for all users + $condition = ['self' => false, 'nurl' => Strings::normaliseLink($url)]; + + $condition['network'] = [Protocol::DFRN, Protocol::DIASPORA, Protocol::ACTIVITYPUB]; DBA::update('contact', $fields, $condition); + // We mustn't set the update fields for OStatus contacts since they are updated in OnePoll + $condition['network'] = Protocol::OSTATUS; + // If the contact failed, propagate the update fields to all contacts if (empty($fields['failed'])) { unset($fields['last-update']); @@ -1758,8 +1765,6 @@ class Contact return; } - // We are polling these contacts, so we mustn't set the update fields here. - $condition['rel'] = [self::FOLLOWER, self::FRIEND]; DBA::update('contact', $fields, $condition); } @@ -1957,7 +1962,7 @@ class Contact $ret['name-date'] = $updated; } - if ($uid == 0) { + if (($uid == 0) || in_array($ret['network'], [Protocol::DFRN, Protocol::DIASPORA, Protocol::ACTIVITYPUB])) { $ret['last-update'] = $updated; $ret['success_update'] = $updated; } @@ -2224,8 +2229,11 @@ class Contact self::updateAvatar($contact_id, $ret['photo']); // pull feed and consume it, which should subscribe to the hub. - - Worker::add(PRIORITY_HIGH, "OnePoll", $contact_id, "force"); + if ($contact['network'] == Protocol::OSTATUS) { + Worker::add(PRIORITY_HIGH, 'OnePoll', $contact_id, 'force'); + } else { + Worker::add(PRIORITY_HIGH, 'UpdateContact', $contact_id); + } $owner = User::getOwnerDataById($user['uid']); diff --git a/src/Module/Contact.php b/src/Module/Contact.php index 4d4508a8cc..f82b7d3cc1 100644 --- a/src/Module/Contact.php +++ b/src/Module/Contact.php @@ -181,9 +181,11 @@ class Contact extends BaseModule if ($result['success']) { DBA::update('contact', ['subhub' => 1], ['id' => $contact_id]); } - } else { + // pull feed and consume it, which should subscribe to the hub. Worker::add(PRIORITY_HIGH, 'OnePoll', $contact_id, 'force'); + } else { + Worker::add(PRIORITY_HIGH, 'UpdateContact', $contact_id); } } diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php index c47e4bd202..18d9de5920 100644 --- a/src/Worker/Cron.php +++ b/src/Worker/Cron.php @@ -61,7 +61,7 @@ class Cron Worker::add(PRIORITY_MEDIUM, 'PollContacts'); // Update contact information - Worker::add(PRIORITY_LOW, 'UpdatePublicContacts'); + Worker::add(PRIORITY_LOW, 'UpdateContacts'); // Update server information Worker::add(PRIORITY_LOW, 'UpdateGServers'); diff --git a/src/Worker/OnePoll.php b/src/Worker/OnePoll.php index 73971a8b1b..bb3dd97198 100644 --- a/src/Worker/OnePoll.php +++ b/src/Worker/OnePoll.php @@ -56,7 +56,7 @@ class OnePoll // We never probe mail contacts since their probing demands a mail from the contact in the inbox. // We don't probe feed accounts by default since they are polled in a higher frequency, but forced probes are okay. - if (!in_array($contact['network'], [Protocol::MAIL, Protocol::FEED]) || ($force && ($contact['network'] == Protocol::FEED))) { + if ($force && ($contact['network'] == Protocol::FEED)) { $success = Contact::updateFromProbe($contact_id); } else { $success = true; diff --git a/src/Worker/PollContacts.php b/src/Worker/PollContacts.php index 078cf202a5..b3ac529de4 100644 --- a/src/Worker/PollContacts.php +++ b/src/Worker/PollContacts.php @@ -41,8 +41,7 @@ class PollContacts $abandon_days = 0; } - $condition = ['network' => [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::OSTATUS, Protocol::FEED, - Protocol::MAIL, Protocol::ZOT, Protocol::PHANTOM], 'self' => false, 'blocked' => false]; + $condition = ['network' => [Protocol::FEED, Protocol::MAIL, Protocol::OSTATUS], 'self' => false, 'blocked' => false]; if (!empty($abandon_days)) { $condition = DBA::mergeConditions($condition, diff --git a/src/Worker/UpdatePublicContacts.php b/src/Worker/UpdateContacts.php similarity index 63% rename from src/Worker/UpdatePublicContacts.php rename to src/Worker/UpdateContacts.php index 939d9fa8d7..2328c7c84a 100644 --- a/src/Worker/UpdatePublicContacts.php +++ b/src/Worker/UpdateContacts.php @@ -29,52 +29,54 @@ use Friendica\DI; use Friendica\Util\DateTimeFormat; /** - * Update public contacts + * Update federated contacts */ -class UpdatePublicContacts +class UpdateContacts { public static function execute() { $count = 0; $ids = []; - $base_condition = ['network' => Protocol::FEDERATED, 'uid' => 0, 'self' => false]; + $base_condition = ['network' => array_merge(Protocol::FEDERATED, [Protocol::ZOT, Protocol::PHANTOM]), 'self' => false]; - $existing = Worker::countWorkersByCommand('UpdateContact'); - Logger::info('Already existing jobs', ['existing' => $existing]); - if ($existing > 100) { + $update_limit = DI::config()->get('system', 'contact_update_limit'); + if (empty($update_limit)) { return; } - $limit = 100 - $existing; - - if (!DI::config()->get('system', 'update_active_contacts')) { - $part = 3; - // Add every contact (mostly failed ones) that hadn't been updated for six months - $condition = DBA::mergeConditions($base_condition, - ["`last-update` < ?", DateTimeFormat::utc('now - 6 month')]); - $ids = self::getContactsToUpdate($condition, $ids, round($limit / $part)); - - // Add every non failed contact that hadn't been updated for a month - $condition = DBA::mergeConditions($base_condition, - ["NOT `failed` AND `last-update` < ?", DateTimeFormat::utc('now - 1 month')]); - $ids = self::getContactsToUpdate($condition, $ids, round($limit / $part)); - } else { - $part = 1; + $updating = Worker::countWorkersByCommand('UpdateContact'); + $limit = $update_limit - $updating; + if ($limit <= 0) { + Logger::info('The number of currently running jobs exceed the limit'); + return; } - // Add every contact our system interacted with and hadn't been updated for a week + // Add every contact our system interacted with and hadn't been updated for a week if unarchived + // or for a month if archived. $condition = DBA::mergeConditions($base_condition, ["(`id` IN (SELECT `author-id` FROM `item`) OR `id` IN (SELECT `owner-id` FROM `item`) OR `id` IN (SELECT `causer-id` FROM `item`) OR - `id` IN (SELECT `cid` FROM `post-tag`) OR `id` IN (SELECT `cid` FROM `user-contact`)) AND - `last-update` < ?", DateTimeFormat::utc('now - 1 week')]); - $ids = self::getContactsToUpdate($condition, $ids, round($limit / $part)); + `id` IN (SELECT `cid` FROM `post-tag`) OR `id` IN (SELECT `cid` FROM `user-contact`) OR `uid` != ?) AND + (`last-update` < ? OR (NOT `archive` AND `last-update` < ?))", + 0, DateTimeFormat::utc('now - 1 month'), DateTimeFormat::utc('now - 1 week')]); + $ids = self::getContactsToUpdate($condition, $ids, $limit - count($ids)); + + Logger::info('Fetched interacting federated contacts', ['count' => count($ids)]); + + if (!DI::config()->get('system', 'update_active_contacts')) { + // Add every contact (mostly failed ones) that hadn't been updated for six months + // and every non failed contact that hadn't been updated for a month + $condition = DBA::mergeConditions($base_condition, + ["(`last-update` < ? OR (NOT `archive` AND `last-update` < ?))", + DateTimeFormat::utc('now - 6 month'), DateTimeFormat::utc('now - 1 month')]); + $ids = self::getContactsToUpdate($condition, $ids, $limit - count($ids)); + } foreach ($ids as $id) { Worker::add(PRIORITY_LOW, "UpdateContact", $id); ++$count; } - Logger::info('Initiated update for public contacts', ['count' => $count]); + Logger::info('Initiated update for federated contacts', ['count' => $count]); } /** diff --git a/static/defaults.config.php b/static/defaults.config.php index 053811b7f1..455272926e 100644 --- a/static/defaults.config.php +++ b/static/defaults.config.php @@ -131,6 +131,10 @@ return [ // Don't display sharing accounts on the global community 'community_no_sharer' => false, + // contact_update_limit (Integer) + // How much contacts should be checked at a time? + 'contact_update_limit' => 100, + // cron_interval (Integer) // Minimal period in minutes between two calls of the "Cron" worker job. 'cron_interval' => 5,