use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1304);
+ define('DB_UPDATE_VERSION', 1305);
}
return [
"hook_file_function" => ["UNIQUE", "hook", "file", "function"],
]
],
+ "inbox-status" => [
+ "comment" => "Status of ActivityPub inboxes",
+ "fields" => [
+ "url" => ["type" => "varbinary(255)", "not null" => "1", "primary" => "1", "comment" => "URL of the inbox"],
+ "created" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Creation date of this entry"],
+ "success" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last successful delivery"],
+ "failure" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Date of the last failed delivery"],
+ "previous" => ["type" => "datetime", "not null" => "1", "default" => DBA::NULL_DATETIME, "comment" => "Previous delivery date"],
+ "archive" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Is the inbox archived?"]
+ ],
+ "indexes" => [
+ "PRIMARY" => ["url"]
+ ]
+ ],
"intro" => [
"comment" => "",
"fields" => [
-- ------------------------------------------
--- Friendica 2019.03-dev (The Tazmans Flax-lily)
--- DB_UPDATE_VERSION 1300
+-- Friendica 2019.03 (Dalmatian Bellflower)
+-- DB_UPDATE_VERSION 1305
-- ------------------------------------------
UNIQUE INDEX `hook_file_function` (`hook`,`file`,`function`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='addon hook registry';
+--
+-- TABLE inbox-status
+--
+CREATE TABLE IF NOT EXISTS `inbox-status` (
+ `url` varbinary(255) NOT NULL COMMENT 'URL of the inbox',
+ `created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Creation date of this entry',
+ `success` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last successful delivery',
+ `failure` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Date of the last failed delivery',
+ `previous` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'Previous delivery date',
+ `archive` boolean NOT NULL DEFAULT '0' COMMENT 'Is the inbox archived?',
+ PRIMARY KEY(`url`)
+) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Status of ActivityPub inboxes';
+
--
-- TABLE intro
--
`deny_gid` mediumtext COMMENT 'Access Control - list of denied groups',
`backend-class` tinytext COMMENT 'Storage backend class',
`backend-ref` text COMMENT 'Storage backend data reference',
- `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT 'edited timestamp',
+ `updated` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '',
PRIMARY KEY(`id`),
INDEX `contactid` (`contact-id`),
INDEX `uid_contactid` (`uid`,`contact-id`),
`retrial` tinyint NOT NULL DEFAULT 0 COMMENT 'Retrial counter',
`done` boolean NOT NULL DEFAULT '0' COMMENT 'Marked 1 when the task was done - will be deleted later',
PRIMARY KEY(`id`),
- INDEX `pid` (`pid`),
- INDEX `parameter` (`parameter`(64)),
- INDEX `priority_created_next_try` (`priority`,`created`,`next_try`),
- INDEX `done_priority_executed_next_try` (`done`,`priority`,`executed`,`next_try`),
- INDEX `done_executed_next_try` (`done`,`executed`,`next_try`),
+ INDEX `done_parameter` (`done`,`parameter`(64)),
+ INDEX `done_executed` (`done`,`executed`),
+ INDEX `done_priority_created` (`done`,`priority`,`created`),
INDEX `done_priority_next_try` (`done`,`priority`,`next_try`),
- INDEX `done_next_try` (`done`,`next_try`)
+ INDEX `done_pid_next_try` (`done`,`pid`,`next_try`),
+ INDEX `done_pid_priority_created` (`done`,`pid`,`priority`,`created`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Background tasks queue entries';
--
return $receivers;
}
+ /**
+ * Check if an inbox is archived
+ *
+ * @param string $url Inbox url
+ *
+ * @return boolean "true" if inbox is archived
+ */
+ private static function archivedInbox($url)
+ {
+ return DBA::exists('inbox-status', ['url' => $url, 'archive' => true]);
+ }
+
/**
* Fetches a list of inboxes of followers of a given user
*
} else {
$target = $profile['sharedinbox'];
}
- $inboxes[$target] = $target;
+ if (!self::archivedInbox($target)) {
+ $inboxes[$target] = $target;
+ }
}
}
DBA::close($contacts);
} else {
$target = $profile['sharedinbox'];
}
- $inboxes[$target] = $target;
+ if (!self::archivedInbox($target)) {
+ $inboxes[$target] = $target;
+ }
}
}
}
*/
namespace Friendica\Util;
+use Friendica\Database\DBA;
use Friendica\Core\Config;
use Friendica\Core\Logger;
use Friendica\Model\User;
Logger::log('Transmit to ' . $target . ' returned ' . $return_code, Logger::DEBUG);
- return ($return_code >= 200) && ($return_code <= 299);
+ $success = ($return_code >= 200) && ($return_code <= 299);
+
+ self::setInboxStatus($target, $success);
+
+ return $success;
+ }
+
+ /**
+ * @brief Set the delivery status for a given inbox
+ *
+ * @param string $url The URL of the inbox
+ * @param boolean $success Transmission status
+ */
+ static private function setInboxStatus($url, $success)
+ {
+ $now = DateTimeFormat::utcNow();
+
+ $status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
+ if (!DBA::isResult($status)) {
+ DBA::insert('inbox-status', ['url' => $url, 'created' => $now]);
+ $status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
+ }
+
+ if ($success) {
+ $fields = ['success' => $now];
+ } else {
+ $fields = ['failure' => $now];
+ }
+
+ if ($status['failure'] > DBA::NULL_DATETIME) {
+ $new_previous_stamp = strtotime($status['failure']);
+ $old_previous_stamp = strtotime($status['previous']);
+
+ // Only set "previous" with at least one day difference.
+ // We use this to assure to not accidentally archive too soon.
+ if (($new_previous_stamp - $old_previous_stamp) >= 86400) {
+ $fields['previous'] = $status['failure'];
+ }
+ }
+
+ if (!$success) {
+ if ($status['success'] <= DBA::NULL_DATETIME) {
+ $stamp1 = strtotime($status['created']);
+ } else {
+ $stamp1 = strtotime($status['success']);
+ }
+
+ $stamp2 = strtotime($now);
+ $previous_stamp = strtotime($status['previous']);
+
+ // Archive the inbox when there had been failures for five days.
+ // Additionally ensure that at least one previous attempt has to be in between.
+ if ((($stamp2 - $stamp1) >= 86400 * 5) && ($previous_stamp > $stamp1)) {
+ $fields['archive'] = true;
+ }
+ } else {
+ $fields['archive'] = false;
+ }
+
+ DBA::update('inbox-status', $fields, ['url' => $url]);
}
/**