From 1532f0d52914cf7e16ed05b3d77d66c3a7771448 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 19 Jul 2020 01:15:57 +0000 Subject: [PATCH] New field "failed" for gserver, gcontact and contact --- src/Model/Contact.php | 14 ++++++++------ src/Model/GContact.php | 26 ++++++++++++++------------ src/Model/GServer.php | 8 +++++--- src/Worker/OnePoll.php | 28 +++++++++++++++++----------- static/dbstructure.config.php | 3 +++ 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 646da57caa..09d5277331 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1029,7 +1029,7 @@ class Contact { // Always unarchive the relay contact entry if (!empty($contact['batch']) && !empty($contact['term-date']) && ($contact['term-date'] > DBA::NULL_DATETIME)) { - $fields = ['term-date' => DBA::NULL_DATETIME, 'archive' => false]; + $fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false]; $condition = ['uid' => 0, 'network' => Protocol::FEDERATED, 'batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY]; DBA::update('contact', $fields, $condition); } @@ -1053,7 +1053,7 @@ class Contact } // It's a miracle. Our dead contact has inexplicably come back to life. - $fields = ['term-date' => DBA::NULL_DATETIME, 'archive' => false]; + $fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false]; DBA::update('contact', $fields, ['id' => $contact['id']]); DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]); GContact::updateFromPublicContactURL($contact['url']); @@ -1495,7 +1495,8 @@ class Contact $updated = [ 'url' => $data['url'], 'nurl' => Strings::normaliseLink($data['url']), - 'updated' => DateTimeFormat::utcNow() + 'updated' => DateTimeFormat::utcNow(), + 'failed' => false ]; $fields = ['addr', 'alias', 'name', 'nick', 'keywords', 'location', 'about', 'baseurl', 'gsid']; @@ -1973,7 +1974,7 @@ class Contact // We check after the probing to be able to correct falsely detected contact types. if (($contact['contact-type'] == self::TYPE_RELAY) && (!Strings::compareLink($ret['url'], $contact['url']) || in_array($ret['network'], [Protocol::FEED, Protocol::PHANTOM]))) { - self::updateContact($id, $uid, $contact['url'], ['last-update' => $updated, 'success_update' => $updated]); + self::updateContact($id, $uid, $contact['url'], ['failed' => false, 'last-update' => $updated, 'success_update' => $updated]); Logger::info('Not updating relais', ['id' => $id, 'url' => $contact['url']]); return true; } @@ -1981,7 +1982,7 @@ class Contact // If Probe::uri fails the network code will be different ("feed" or "unkn") if (in_array($ret['network'], [Protocol::FEED, Protocol::PHANTOM]) && ($ret['network'] != $contact['network'])) { if ($force && ($uid == 0)) { - self::updateContact($id, $uid, $ret['url'], ['last-update' => $updated, 'failure_update' => $updated]); + self::updateContact($id, $uid, $ret['url'], ['failed' => true, 'last-update' => $updated, 'failure_update' => $updated]); } return false; } @@ -2025,7 +2026,7 @@ class Contact if (!$update) { if ($force) { - self::updateContact($id, $uid, $ret['url'], ['last-update' => $updated, 'success_update' => $updated]); + self::updateContact($id, $uid, $ret['url'], ['failed' => false, 'last-update' => $updated, 'success_update' => $updated]); } // Update the public contact @@ -2055,6 +2056,7 @@ class Contact if ($force && ($uid == 0)) { $ret['last-update'] = $updated; $ret['success_update'] = $updated; + $ret['failed'] = false; } unset($ret['photo']); diff --git a/src/Model/GContact.php b/src/Model/GContact.php index 5ef74dcf77..00867475a8 100644 --- a/src/Model/GContact.php +++ b/src/Model/GContact.php @@ -231,6 +231,7 @@ class GContact } $gcontact['server_url'] = $data['baseurl']; + $gcontact['failed'] = false; $gcontact = array_merge($gcontact, $data); } @@ -642,7 +643,7 @@ class GContact $fields = ['name' => $contact['name'], 'nick' => $contact['nick'] ?? '', 'addr' => $contact['addr'] ?? '', 'network' => $contact['network'], 'url' => $contact['url'], 'nurl' => Strings::normaliseLink($contact['url']), 'photo' => $contact['photo'], 'created' => DateTimeFormat::utcNow(), 'updated' => DateTimeFormat::utcNow(), 'location' => $contact['location'], - 'about' => $contact['about'], 'hide' => $contact['hide'], 'generation' => $contact['generation']]; + 'about' => $contact['about'], 'hide' => $contact['hide'], 'generation' => $contact['generation'], 'failed' => false]; DBA::insert('gcontact', $fields); @@ -681,7 +682,7 @@ class GContact } $public_contact = DBA::selectFirst('gcontact', [ - 'name', 'nick', 'photo', 'location', 'about', 'addr', 'generation', 'birthday', 'keywords', 'gsid', + 'name', 'nick', 'photo', 'location', 'about', 'addr', 'generation', 'birthday', 'keywords', 'gsid', 'failed', 'contact-type', 'hide', 'nsfw', 'network', 'alias', 'notify', 'server_url', 'connect', 'updated', 'url' ], ['id' => $gcontact_id]); @@ -787,7 +788,7 @@ class GContact 'location' => $contact['location'], 'about' => $contact['about'], 'generation' => $contact['generation'], 'updated' => $contact['updated'], 'server_url' => $contact['server_url'], 'connect' => $contact['connect'], - 'gsid' => $contact['gsid'] + 'failed' => $contact['failed'], 'gsid' => $contact['gsid'] ]; DBA::update('gcontact', $updated, $condition, $fields); @@ -851,13 +852,13 @@ class GContact $noscrape = json_decode($curlResult->getBody(), true); if (!empty($noscrape) && !empty($noscrape['updated'])) { $noscrape['updated'] = DateTimeFormat::utc($noscrape['updated'], DateTimeFormat::MYSQL); - $fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $noscrape['updated']]; + $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $noscrape['updated']]; DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]); return true; } } elseif ($curlResult->isTimeout()) { // On a timeout return the existing value, but mark the contact as failure - $fields = ['last_failure' => DateTimeFormat::utcNow()]; + $fields = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()]; DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]); return true; } @@ -915,7 +916,7 @@ class GContact return; } - $fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated]; + $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated]; DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]); } @@ -929,7 +930,7 @@ class GContact // Search for the newest entry in the feed $curlResult = Network::curl($data['poll']); if (!$curlResult->isSuccess()) { - $fields = ['last_failure' => DateTimeFormat::utcNow()]; + $fields = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()]; DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]); Logger::info("Profile wasn't reachable (no feed)", ['url' => $data['url']]); @@ -970,7 +971,7 @@ class GContact return; } - $fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated]; + $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated]; DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]); } /** @@ -1012,7 +1013,7 @@ class GContact $fields = ['name', 'nick', 'url', 'nurl', 'location', 'about', 'keywords', 'bd', 'contact-type', 'network', 'addr', 'notify', 'alias', 'archive', 'term-date', 'created', 'updated', 'avatar', 'success_update', 'failure_update', 'forum', 'prv', - 'baseurl', 'gsid', 'sensitive', 'unsearchable']; + 'baseurl', 'gsid', 'sensitive', 'unsearchable', 'failed']; $contact = DBA::selectFirst('contact', $fields, array_merge($condition, ['uid' => 0, 'network' => Protocol::FEDERATED])); if (!DBA::isResult($contact)) { @@ -1022,7 +1023,7 @@ class GContact $fields = ['name', 'nick', 'url', 'nurl', 'location', 'about', 'keywords', 'generation', 'birthday', 'contact-type', 'network', 'addr', 'notify', 'alias', 'archived', 'archive_date', 'created', 'updated', 'photo', 'last_contact', 'last_failure', 'community', 'connect', - 'server_url', 'gsid', 'nsfw', 'hide', 'id']; + 'server_url', 'gsid', 'nsfw', 'hide', 'id', 'failed']; $old_gcontact = DBA::selectFirst('gcontact', $fields, ['nurl' => $contact['nurl']]); $do_insert = !DBA::isResult($old_gcontact); @@ -1034,7 +1035,7 @@ class GContact // These fields are identical in both contact and gcontact $fields = ['name', 'nick', 'url', 'nurl', 'location', 'about', 'keywords', 'gsid', - 'contact-type', 'network', 'addr', 'notify', 'alias', 'created', 'updated']; + 'contact-type', 'network', 'addr', 'notify', 'alias', 'created', 'updated', 'failed']; foreach ($fields as $field) { $gcontact[$field] = $contact[$field]; @@ -1100,13 +1101,14 @@ class GContact $data = Probe::uri($url, $force); if (in_array($data['network'], [Protocol::PHANTOM])) { - $fields = ['last_failure' => DateTimeFormat::utcNow()]; + $fields = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()]; DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($url)]); Logger::info('Invalid network for contact', ['url' => $data['url'], 'callstack' => System::callstack()]); return false; } $data['server_url'] = $data['baseurl']; + $data['failed'] = false; self::update($data); diff --git a/src/Model/GServer.php b/src/Model/GServer.php index fdbc775098..23056906c2 100644 --- a/src/Model/GServer.php +++ b/src/Model/GServer.php @@ -235,14 +235,14 @@ class GServer private static function setFailure(string $url) { if (DBA::exists('gserver', ['nurl' => Strings::normaliseLink($url)])) { - DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow(), 'detection-method' => null], + DBA::update('gserver', ['failed' => true, 'last_failure' => DateTimeFormat::utcNow(), 'detection-method' => null], ['nurl' => Strings::normaliseLink($url)]); Logger::info('Set failed status for existing server', ['url' => $url]); return; } DBA::insert('gserver', ['url' => $url, 'nurl' => Strings::normaliseLink($url), 'network' => Protocol::PHANTOM, 'created' => DateTimeFormat::utcNow(), - 'last_failure' => DateTimeFormat::utcNow()]); + 'failed' => true, 'last_failure' => DateTimeFormat::utcNow()]); Logger::info('Set failed status for new server', ['url' => $url]); } @@ -303,7 +303,8 @@ class GServer // If the URL missmatches, then we mark the old entry as failure if ($url != $original_url) { - DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => Strings::normaliseLink($original_url)]); + DBA::update('gserver', ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()], + ['nurl' => Strings::normaliseLink($original_url)]); } // When a nodeinfo is present, we don't need to dig further @@ -449,6 +450,7 @@ class GServer } $serverdata['last_contact'] = DateTimeFormat::utcNow(); + $serverdata['failed'] = false; $gserver = DBA::selectFirst('gserver', ['network'], ['nurl' => Strings::normaliseLink($url)]); if (!DBA::isResult($gserver)) { diff --git a/src/Worker/OnePoll.php b/src/Worker/OnePoll.php index a2659f4e76..1798612108 100644 --- a/src/Worker/OnePoll.php +++ b/src/Worker/OnePoll.php @@ -165,7 +165,7 @@ class OnePoll if (!strstr($xml, '<')) { Logger::log('post_handshake: response from ' . $url . ' did not contain XML.'); - $fields = ['last-update' => $updated, 'failure_update' => $updated]; + $fields = ['failed' => true, 'last-update' => $updated, 'failure_update' => $updated]; self::updateContact($contact, $fields); Contact::markForArchival($contact); return; @@ -213,10 +213,10 @@ class OnePoll } } - self::updateContact($contact, ['last-update' => $updated, 'success_update' => $updated]); + self::updateContact($contact, ['failed' => false, 'last-update' => $updated, 'success_update' => $updated]); Contact::unmarkForArchival($contact); } elseif (in_array($contact["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::FEED])) { - self::updateContact($contact, ['last-update' => $updated, 'failure_update' => $updated]); + self::updateContact($contact, ['failed' => true, 'last-update' => $updated, 'failure_update' => $updated]); Contact::markForArchival($contact); } else { self::updateContact($contact, ['last-update' => $updated]); @@ -244,8 +244,14 @@ class OnePoll */ private static function updateContact(array $contact, array $fields) { + // Update the user's contact DBA::update('contact', $fields, ['id' => $contact['id']]); + + // Update the public contact DBA::update('contact', $fields, ['uid' => 0, 'nurl' => $contact['nurl']]); + + // Update the rest of the contacts that aren't polled + DBA::update('contact', $fields, ['rel' => Contact::FOLLOWER, 'nurl' => $contact['nurl']]); } /** @@ -289,7 +295,7 @@ class OnePoll if (!$curlResult->isSuccess() && ($curlResult->getErrorNumber() == CURLE_OPERATION_TIMEDOUT)) { // set the last-update so we don't keep polling - self::updateContact($contact, ['last-update' => $updated]); + self::updateContact($contact, ['failed' => true, 'last-update' => $updated]); Contact::markForArchival($contact); Logger::log('Contact archived'); return false; @@ -307,7 +313,7 @@ class OnePoll Logger::log("$url appears to be dead - marking for death "); // set the last-update so we don't keep polling - $fields = ['last-update' => $updated, 'failure_update' => $updated]; + $fields = ['failed' => true, 'last-update' => $updated, 'failure_update' => $updated]; self::updateContact($contact, $fields); Contact::markForArchival($contact); return false; @@ -316,7 +322,7 @@ class OnePoll if (!strstr($handshake_xml, '<')) { Logger::log('response from ' . $url . ' did not contain XML.'); - $fields = ['last-update' => $updated, 'failure_update' => $updated]; + $fields = ['failed' => true, 'last-update' => $updated, 'failure_update' => $updated]; self::updateContact($contact, $fields); Contact::markForArchival($contact); return false; @@ -327,7 +333,7 @@ class OnePoll if (!is_object($res)) { Logger::info('Unparseable response', ['url' => $url]); - $fields = ['last-update' => $updated, 'failure_update' => $updated]; + $fields = ['failed' => true, 'last-update' => $updated, 'failure_update' => $updated]; self::updateContact($contact, $fields); Contact::markForArchival($contact); return false; @@ -338,7 +344,7 @@ class OnePoll Logger::log("$url replied status 1 - marking for death "); // set the last-update so we don't keep polling - $fields = ['last-update' => $updated, 'failure_update' => $updated]; + $fields = ['failed' => true, 'last-update' => $updated, 'failure_update' => $updated]; self::updateContact($contact, $fields); Contact::markForArchival($contact); } elseif ($contact['term-date'] > DBA::NULL_DATETIME) { @@ -417,7 +423,7 @@ class OnePoll // Will only do this once per notify-enabled OStatus contact // or if relationship changes - $stat_writeable = ((($contact['notify']) && ($contact['rel'] == Contact::FOLLOWER || $contact['rel'] == Contact::FRIEND)) ? 1 : 0); + $stat_writeable = $contact['notify'] && ($contact['rel'] == Contact::FOLLOWER || $contact['rel'] == Contact::FRIEND); // Contacts from OStatus are always writable if ($protocol === Protocol::OSTATUS) { @@ -443,7 +449,7 @@ class OnePoll if ($curlResult->isTimeout()) { // set the last-update so we don't keep polling - self::updateContact($contact, ['last-update' => $updated]); + self::updateContact($contact, ['failed' => true, 'last-update' => $updated]); Contact::markForArchival($contact); Logger::log('Contact archived'); return false; @@ -467,7 +473,7 @@ class OnePoll $mail_disabled = ((function_exists('imap_open') && !DI::config()->get('system', 'imap_disabled')) ? 0 : 1); if ($mail_disabled) { // set the last-update so we don't keep polling - self::updateContact($contact, ['last-update' => $updated]); + self::updateContact($contact, ['failed' => true, 'last-update' => $updated]); Contact::markForArchival($contact); Logger::log('Contact archived'); return; diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index bab158d036..8908ba13aa 100755 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -82,6 +82,7 @@ return [ "last_poco_query" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], "last_contact" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], "last_failure" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], + "failed" => ["type" => "boolean", "comment" => "Connection failed"], ], "indexes" => [ "PRIMARY" => ["id"], @@ -151,6 +152,7 @@ return [ "last-update" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last try to update the contact info"], "success_update" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last successful contact update"], "failure_update" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last failed update"], + "failed" => ["type" => "boolean", "comment" => "Connection failed"], "name-date" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""], "uri-date" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""], "avatar-date" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => ""], @@ -558,6 +560,7 @@ return [ "last_contact" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], "last_failure" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], "last_discovery" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last contact discovery"], + "failed" => ["type" => "boolean", "comment" => "Connection failed"], "archive_date" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], "archived" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""], "location" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],