From f022a49f9e1462dd48e8a97bde43e533c0e680c6 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sat, 31 Dec 2022 16:01:40 +0000
Subject: [PATCH] New "Defunct" check

---
 src/Model/GServer.php   | 41 +++++++++++++++++++++++++++++++++++++++++
 src/Worker/Notifier.php |  3 +--
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/src/Model/GServer.php b/src/Model/GServer.php
index 98acc9b67d..8adabf847e 100644
--- a/src/Model/GServer.php
+++ b/src/Model/GServer.php
@@ -164,6 +164,39 @@ class GServer
 		return DI::dba()->toArray($stmt);
 	}
 
+	/**
+	 * Checks if the given server array is unreachable for a long time now
+	 *
+	 * @param integer $gsid
+	 * @return boolean
+	 */
+	private static function defunctByArray(array $gserver): bool
+	{
+		return ($gserver['failed'] || in_array($gserver['network'], Protocol::FEDERATED)) &&
+			($gserver['last_contact'] >= $gserver['created']) &&
+			($gserver['last_contact'] < $gserver['last_failure']) &&
+			($gserver['last_contact'] < DateTimeFormat::utc('now - 90 days'));
+	}
+
+	/**
+	 * Checks if the given server id is unreachable for a long time now
+	 *
+	 * @param integer $gsid
+	 * @return boolean
+	 */
+	public static function defunct(int $gsid): bool
+	{
+		$gserver = DBA::selectFirst('gserver', ['url', 'next_contact', 'last_contact', 'last_failure', 'created', 'failed', 'network'], ['id' => $gsid]);
+		if (empty($gserver)) {
+			return false;
+		} else {
+			if (strtotime($gserver['next_contact']) < time()) {
+				Worker::add(Worker::PRIORITY_LOW, 'UpdateGServer', $gserver['url'], false);
+			}
+			return self::defunctByArray($gserver);
+		}
+	}
+
 	/**
 	 * Checks if the given server id is reachable
 	 *
@@ -374,6 +407,9 @@ class GServer
 			'next_contact' => $next_update, 'network' => Protocol::PHANTOM, 'detection-method' => null],
 			['nurl' => Strings::normaliseLink($url)]);
 			Logger::info('Set failed status for existing server', ['url' => $url]);
+			if (self::defunctByArray($gserver)) {
+				Contact::update(['archive' => true], ['gsid' => $gserver['id']]);
+			}
 			return;
 		}
 		self::insert(['url' => $url, 'nurl' => Strings::normaliseLink($url),
@@ -617,6 +653,11 @@ class GServer
 			$serverdata = self::detectNetworkViaContacts($url, $serverdata);
 		}
 
+		if (($serverdata['network'] == Protocol::PHANTOM) && in_array($serverdata['detection-method'], [self::DETECT_MANUAL, self::DETECT_BODY])) {
+			self::setFailure($url);
+			return false;
+		}
+
 		// Detect the directory type
 		$serverdata['directory-type'] = self::DT_NONE;
 
diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php
index 0dd144a485..b9b9441003 100644
--- a/src/Worker/Notifier.php
+++ b/src/Worker/Notifier.php
@@ -570,8 +570,7 @@ class Notifier
 			} elseif (!DI::config()->get('system', 'bulk_delivery')) {
 				$reachable = !GServer::reachableById($contact['gsid']);
 			} else {
-				// On bulk delivery we don't check the server status at this point
-				$reachable = true;
+				$reachable = !GServer::defunct($contact['gsid']);
 			}
 
 			if (!$reachable) {
-- 
2.39.5