}
// 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);
+ }
+ }
+
+ if ($contact['uid'] != 0) {
+ return;
}
- $condition = ['self' => false, 'nurl' => Strings::normaliseLink($url), 'network' => Protocol::FEDERATED];
+ // Update contact data for all users
+ $condition = ['self' => false, 'nurl' => Strings::normaliseLink($url)];
- // 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;
+ $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']);
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);
}
$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;
}
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']);
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);
}
}
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');
// 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;
$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,
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2020, Friendica
+ *
+ * @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\Worker;
+
+use Friendica\Core\Logger;
+use Friendica\Core\Protocol;
+use Friendica\Core\Worker;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Util\DateTimeFormat;
+
+/**
+ * Update federated contacts
+ */
+class UpdateContacts
+{
+ public static function execute()
+ {
+ $count = 0;
+ $ids = [];
+ $base_condition = ['network' => array_merge(Protocol::FEDERATED, [Protocol::ZOT, Protocol::PHANTOM]), 'self' => false];
+
+ $update_limit = DI::config()->get('system', 'contact_update_limit');
+ if (empty($update_limit)) {
+ return;
+ }
+
+ $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 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`) 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 federated contacts', ['count' => $count]);
+ }
+
+ /**
+ * Returns contact ids based on a given condition
+ *
+ * @param array $condition
+ * @param array $ids
+ * @return array contact ids
+ */
+ private static function getContactsToUpdate(array $condition, array $ids = [], int $limit)
+ {
+ $contacts = DBA::select('contact', ['id'], $condition, ['limit' => $limit, 'order' => ['last-update']]);
+ while ($contact = DBA::fetch($contacts)) {
+ $ids[] = $contact['id'];
+ }
+ DBA::close($contacts);
+ return $ids;
+ }
+}
+++ /dev/null
-<?php
-/**
- * @copyright Copyright (C) 2020, Friendica
- *
- * @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\Worker;
-
-use Friendica\Core\Logger;
-use Friendica\Core\Protocol;
-use Friendica\Core\Worker;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Util\DateTimeFormat;
-
-/**
- * Update public contacts
- */
-class UpdatePublicContacts
-{
- public static function execute()
- {
- $count = 0;
- $ids = [];
- $base_condition = ['network' => Protocol::FEDERATED, 'uid' => 0, 'self' => false];
-
- $existing = Worker::countWorkersByCommand('UpdateContact');
- Logger::info('Already existing jobs', ['existing' => $existing]);
- if ($existing > 100) {
- 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;
- }
-
- // Add every contact our system interacted with and hadn't been updated for a week
- $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));
-
- foreach ($ids as $id) {
- Worker::add(PRIORITY_LOW, "UpdateContact", $id);
- ++$count;
- }
-
- Logger::info('Initiated update for public contacts', ['count' => $count]);
- }
-
- /**
- * Returns contact ids based on a given condition
- *
- * @param array $condition
- * @param array $ids
- * @return array contact ids
- */
- private static function getContactsToUpdate(array $condition, array $ids = [], int $limit)
- {
- $contacts = DBA::select('contact', ['id'], $condition, ['limit' => $limit, 'order' => ['last-update']]);
- while ($contact = DBA::fetch($contacts)) {
- $ids[] = $contact['id'];
- }
- DBA::close($contacts);
- return $ids;
- }
-}
// 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,