From d5d2892f59c7eea58eca11ae4af8b80da9ef2133 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 12 May 2022 06:17:55 +0000 Subject: [PATCH 01/13] Simplifications for the experimental bulk delivery --- src/Worker/APDelivery.php | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 37b47dd46d..83e47172fc 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -61,29 +61,15 @@ class APDelivery $result = self::deliver($inbox); $success = $result['success']; $uri_ids = $result['uri_ids']; - } - - if (empty($uri_ids)) { + } else { $success = self::deliverToInbox($cmd, $item_id, $inbox, $uid, $receivers, $uri_id); + $uri_ids = [$uri_id]; } if (!$success && !Worker::defer() && in_array($cmd, [Delivery::POST])) { - if (!empty($uri_id)) { + foreach ($uri_ids as $uri_id) { Post\Delivery::remove($uri_id, $inbox); Post\DeliveryData::incrementQueueFailed($uri_id); - } elseif (!empty($uri_ids)) { - foreach ($uri_ids as $uri_id) { - Post\Delivery::remove($uri_id, $inbox); - Post\DeliveryData::incrementQueueFailed($uri_id); - } - } - } elseif ($success && in_array($cmd, [Delivery::POST])) { - if (!empty($uri_id)) { - Post\DeliveryData::incrementQueueDone($uri_id, Post\DeliveryData::ACTIVITYPUB); - } elseif (!empty($uri_ids)) { - foreach ($uri_ids as $uri_id) { - Post\DeliveryData::incrementQueueDone($uri_id, Post\DeliveryData::ACTIVITYPUB); - } } } } @@ -91,13 +77,14 @@ class APDelivery private static function deliver(string $inbox) { $uri_ids = []; - $success = true; + $posts = Post\Delivery::selectForInbox($inbox); + $success = empty($posts); - $posts = Post\Delivery::selectForInbox($inbox); foreach ($posts as $post) { - $uri_ids[] = $post['uri-id']; - if ($success) { - $success = self::deliverToInbox($post['command'], 0, $inbox, $post['uid'], [], $post['uri-id']); + if (self::deliverToInbox($post['command'], 0, $inbox, $post['uid'], [], $post['uri-id'])) { + $success = true; + } else { + $uri_ids[] = $post['uri-id']; } } @@ -119,7 +106,7 @@ class APDelivery if (empty($receivers)) { $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid, true); $receivers = $inboxes[$inbox] ?? []; - } + } } } @@ -154,6 +141,10 @@ class APDelivery Logger::info('Delivered', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $item_id, 'uri-id' => $uri_id, 'uid' => $uid, 'success' => $success]); + if ($success && in_array($cmd, [Delivery::POST])) { + Post\DeliveryData::incrementQueueDone($uri_id, Post\DeliveryData::ACTIVITYPUB); + } + return $success; } From a943dbb420ca81e63b8ec3c1e508d55004424daf Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 12 May 2022 06:54:58 +0000 Subject: [PATCH 02/13] Introducing the "failed" counter --- database.sql | 3 ++- doc/database/db_post-delivery.md | 1 + src/Model/Post/Delivery.php | 13 ++++++++++++- src/Worker/APDelivery.php | 8 ++++++-- static/dbstructure.config.php | 3 ++- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/database.sql b/database.sql index 1d632eb3fb..1508f358dc 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2022.05-rc (Siberian Iris) --- DB_UPDATE_VERSION 1461 +-- DB_UPDATE_VERSION 1462 -- ------------------------------------------ @@ -1126,6 +1126,7 @@ CREATE TABLE IF NOT EXISTS `post-delivery` ( `uid` mediumint unsigned COMMENT 'Delivering user', `created` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '', `command` varbinary(32) COMMENT '', + `failed` tinyint DEFAULT 0 COMMENT 'Number of times the delivery has failed', PRIMARY KEY(`uri-id`,`inbox-id`), INDEX `inbox-id_created` (`inbox-id`,`created`), INDEX `uid` (`uid`), diff --git a/doc/database/db_post-delivery.md b/doc/database/db_post-delivery.md index 79e858193a..8b149b5715 100644 --- a/doc/database/db_post-delivery.md +++ b/doc/database/db_post-delivery.md @@ -13,6 +13,7 @@ Fields | uid | Delivering user | mediumint unsigned | YES | | NULL | | | created | | datetime | YES | | 0001-01-01 00:00:00 | | | command | | varbinary(32) | YES | | NULL | | +| failed | Number of times the delivery has failed | tinyint | YES | | 0 | | Indexes ------------ diff --git a/src/Model/Post/Delivery.php b/src/Model/Post/Delivery.php index 8cd01c3a85..9ccfdc15a6 100644 --- a/src/Model/Post/Delivery.php +++ b/src/Model/Post/Delivery.php @@ -57,8 +57,19 @@ class Delivery DBA::delete('post-delivery', ['uri-id' => $uri_id, 'inbox-id' => ItemURI::getIdByURI($inbox)]); } + /** + * Increment "failed" counter for the given inbox and post + * + * @param integer $uri_id + * @param string $inbox + */ + public static function incrementFailed(int $uri_id, string $inbox) + { + return DBA::e('UPDATE `post-delivery` SET `failed` = `failed` + 1 WHERE `uri-id` = ? AND `inbox-id` = ?', $uri_id, ItemURI::getIdByURI($inbox)); + } + public static function selectForInbox(string $inbox) { - return DBA::selectToArray('post-delivery', [], ['inbox-id' => ItemURI::getIdByURI($inbox)], ['order' => ['created']]); + return DBA::selectToArray('post-delivery', [], ["`inbox-id` = ? AND `failed` < ?", ItemURI::getIdByURI($inbox), 15], ['order' => ['created']]); } } diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 83e47172fc..4091a89bc7 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -131,8 +131,12 @@ class APDelivery $data = ActivityPub\Transmitter::createCachedActivityFromItem($item_id); if (!empty($data)) { $success = HTTPSignature::transmit($data, $inbox, $uid); - if ($success && $uri_id) { - Post\Delivery::remove($uri_id, $inbox); + if ($uri_id) { + if ($success) { + Post\Delivery::remove($uri_id, $inbox); + } else { + Post\Delivery::incrementFailed($uri_id, $inbox); + } } } } diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 08634290b7..101e3da343 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1461); + define('DB_UPDATE_VERSION', 1462); } return [ @@ -1165,6 +1165,7 @@ return [ "uid" => ["type" => "mediumint unsigned", "foreign" => ["user" => "uid"], "comment" => "Delivering user"], "created" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], "command" => ["type" => "varbinary(32)", "comment" => ""], + "failed" => ["type" => "tinyint", "default" => 0, "comment" => "Number of times the delivery has failed"], ], "indexes" => [ "PRIMARY" => ["uri-id", "inbox-id"], From b0b67f1fde8658aefb1f4152894f381ae7f3a871 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 12 May 2022 12:43:49 +0000 Subject: [PATCH 03/13] Remove failing posts --- src/Model/Post/Delivery.php | 13 ++++++++++++- src/Worker/APDelivery.php | 9 ++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Model/Post/Delivery.php b/src/Model/Post/Delivery.php index 9ccfdc15a6..8d19f8c941 100644 --- a/src/Model/Post/Delivery.php +++ b/src/Model/Post/Delivery.php @@ -24,6 +24,7 @@ namespace Friendica\Model\Post; use Friendica\Database\DBA; use BadMethodCallException; use Friendica\Database\Database; +use Friendica\DI; use Friendica\Model\ItemURI; class Delivery @@ -57,6 +58,16 @@ class Delivery DBA::delete('post-delivery', ['uri-id' => $uri_id, 'inbox-id' => ItemURI::getIdByURI($inbox)]); } + /** + * Remove failed posts for an inbox + * + * @param string $inbox + */ + public static function removeFailed(string $inbox) + { + DBA::delete('post-delivery', ["`inbox-id` = ? AND `failed` >= ?", ItemURI::getIdByURI($inbox), DI::config()->get('system', 'worker_defer_limit')]); + } + /** * Increment "failed" counter for the given inbox and post * @@ -70,6 +81,6 @@ class Delivery public static function selectForInbox(string $inbox) { - return DBA::selectToArray('post-delivery', [], ["`inbox-id` = ? AND `failed` < ?", ItemURI::getIdByURI($inbox), 15], ['order' => ['created']]); + return DBA::selectToArray('post-delivery', [], ['inbox-id' => ItemURI::getIdByURI($inbox)], ['order' => ['created']]); } } diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 4091a89bc7..caf89781e5 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -76,19 +76,18 @@ class APDelivery private static function deliver(string $inbox) { + Post\Delivery::removeFailed($inbox); + $uri_ids = []; $posts = Post\Delivery::selectForInbox($inbox); - $success = empty($posts); foreach ($posts as $post) { - if (self::deliverToInbox($post['command'], 0, $inbox, $post['uid'], [], $post['uri-id'])) { - $success = true; - } else { + if (!self::deliverToInbox($post['command'], 0, $inbox, $post['uid'], [], $post['uri-id'])) { $uri_ids[] = $post['uri-id']; } } - return ['success' => $success, 'uri_ids' => $uri_ids]; + return ['success' => empty($uri_ids), 'uri_ids' => $uri_ids]; } private static function deliverToInbox(string $cmd, int $item_id, string $inbox, int $uid, array $receivers, int $uri_id) From 67a74c15e1795540c2b0f8d9a364bee08098dbcb Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 12 May 2022 21:10:59 +0000 Subject: [PATCH 04/13] Improve item fetching --- src/Worker/APDelivery.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index caf89781e5..b3667d653c 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -87,13 +87,14 @@ class APDelivery } } + Logger::debug('Inbox delivery done', ['inbox' => $inbox, 'posts' => count($posts), 'failed' => count($uri_ids)]); return ['success' => empty($uri_ids), 'uri_ids' => $uri_ids]; } private static function deliverToInbox(string $cmd, int $item_id, string $inbox, int $uid, array $receivers, int $uri_id) { if (empty($item_id) && !empty($uri_id) && !empty($uid)) { - $item = Post::selectFirst(['id', 'parent', 'origin'], ['uri-id' => $uri_id, 'uid' => $uid]); + $item = Post::selectFirst(['id', 'parent', 'origin'], ['uri-id' => $uri_id, 'uid' => [$uid, 0]], ['order' => ['uid' => true]]); $item_id = $item['id'] ?? 0; if (empty($receivers) && !empty($item)) { $parent = Post::selectFirst(Item::DELIVER_FIELDLIST, ['id' => $item['parent']]); @@ -106,6 +107,10 @@ class APDelivery $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid, true); $receivers = $inboxes[$inbox] ?? []; } + } elseif (empty($item_id)) { + Logger::debug('Item not found, removing delivery', ['uri-id' => $uri_id, 'uid' => $uid, 'cmd' => $cmd, 'inbox' => $inbox]); + Post\Delivery::remove($uri_id, $inbox); + return true; } } @@ -142,7 +147,7 @@ class APDelivery self::setSuccess($receivers, $success); - Logger::info('Delivered', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $item_id, 'uri-id' => $uri_id, 'uid' => $uid, 'success' => $success]); + Logger::info('Delivered', ['uri-id' => $uri_id, 'uid' => $uid, 'item_id' => $item_id, 'cmd' => $cmd, 'inbox' => $inbox, 'success' => $success]); if ($success && in_array($cmd, [Delivery::POST])) { Post\DeliveryData::incrementQueueDone($uri_id, Post\DeliveryData::ACTIVITYPUB); From 4f68be82efdbbbceffaec4b9ec43be51d1b68130 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 12 May 2022 21:28:57 +0000 Subject: [PATCH 05/13] Use a simpler worker call --- src/Worker/Notifier.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 48b81b9a99..66c3cadbd1 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -789,7 +789,7 @@ class Notifier if (DI::config()->get('system', 'bulk_delivery')) { $delivery_queue_count++; Post\Delivery::add($target_item['uri-id'], $uid, $inbox, $target_item['created'], $cmd); - Worker::add(['priority' => $priority, 'dont_fork' => true], 'APDelivery', $cmd, 0, $inbox, $uid); + Worker::add(PRIORITY_HIGH, 'APDelivery', '', 0, $inbox, 0); } else { if (Worker::add(['priority' => $priority, 'created' => $created, 'dont_fork' => true], 'APDelivery', $cmd, $target_item['id'], $inbox, $uid, $receivers, $target_item['uri-id'])) { @@ -805,7 +805,7 @@ class Notifier if (DI::config()->get('system', 'bulk_delivery')) { $delivery_queue_count++; Post\Delivery::add($target_item['uri-id'], $uid, $inbox, $target_item['created'], $cmd); - Worker::add(['priority' => $priority, 'dont_fork' => true], 'APDelivery', $cmd, 0, $inbox, $uid); + Worker::add(PRIORITY_MEDIUM, 'APDelivery', '', 0, $inbox, 0); } else { if (Worker::add(['priority' => $priority, 'dont_fork' => true], 'APDelivery', $cmd, $target_item['id'], $inbox, $uid, [], $target_item['uri-id'])) { $delivery_queue_count++; From 2049fbce91c66e8aeb561cb578fb9f9374443d4b Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 May 2022 02:11:02 +0000 Subject: [PATCH 06/13] Remove delivery when the inbox is archived --- src/Worker/APDelivery.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index b3667d653c..1ec0ba47ce 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -47,10 +47,14 @@ class APDelivery public static function execute(string $cmd, int $item_id, string $inbox, int $uid, array $receivers = [], int $uri_id = 0) { if (ActivityPub\Transmitter::archivedInbox($inbox)) { - Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $item_id, 'uid' => $uid]); + Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $item_id, 'uri-id' => $uri_id, 'uid' => $uid]); if (in_array($cmd, [Delivery::POST])) { - $item = Post::selectFirst(['uri-id'], ['id' => $item_id]); - Post\DeliveryData::incrementQueueFailed($item['uri-id'] ?? 0); + if (empty($uri_id)) { + $item = Post::selectFirst(['uri-id'], ['id' => $item_id]); + $uri_id = $item['uri-id'] ?? 0; + } + Post\Delivery::remove($uri_id, $inbox); + Post\DeliveryData::incrementQueueFailed($uri_id); } return; } From 2595b5e12f525c86d6e941579bf41cad3eafe76d Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 May 2022 02:18:46 +0000 Subject: [PATCH 07/13] Remove all posts of a given inbox --- src/Worker/APDelivery.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 1ec0ba47ce..3fb389313f 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -49,12 +49,21 @@ class APDelivery if (ActivityPub\Transmitter::archivedInbox($inbox)) { Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $item_id, 'uri-id' => $uri_id, 'uid' => $uid]); if (in_array($cmd, [Delivery::POST])) { - if (empty($uri_id)) { + if (empty($uri_id) && !empty($item_id)) { $item = Post::selectFirst(['uri-id'], ['id' => $item_id]); $uri_id = $item['uri-id'] ?? 0; } - Post\Delivery::remove($uri_id, $inbox); - Post\DeliveryData::incrementQueueFailed($uri_id); + if (empty($uri_id)) { + $posts = Post\Delivery::selectForInbox($inbox); + $uri_ids = array_column($posts, 'uri-id'); + } else { + $uri_ids = [$uri_id]; + } + + foreach ($uri_ids as $uri_id) { + Post\Delivery::remove($uri_id, $inbox); + Post\DeliveryData::incrementQueueFailed($uri_id); + } } return; } From 201610dfe6acbc3756fcd106328312d0ce6cf22c Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Fri, 13 May 2022 04:24:22 +0200 Subject: [PATCH 08/13] Don't look at the command when archiving an inbox --- src/Worker/APDelivery.php | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 3fb389313f..641f27fce4 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -48,22 +48,20 @@ class APDelivery { if (ActivityPub\Transmitter::archivedInbox($inbox)) { Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $item_id, 'uri-id' => $uri_id, 'uid' => $uid]); - if (in_array($cmd, [Delivery::POST])) { - if (empty($uri_id) && !empty($item_id)) { - $item = Post::selectFirst(['uri-id'], ['id' => $item_id]); - $uri_id = $item['uri-id'] ?? 0; - } - if (empty($uri_id)) { - $posts = Post\Delivery::selectForInbox($inbox); - $uri_ids = array_column($posts, 'uri-id'); - } else { - $uri_ids = [$uri_id]; - } - - foreach ($uri_ids as $uri_id) { - Post\Delivery::remove($uri_id, $inbox); - Post\DeliveryData::incrementQueueFailed($uri_id); - } + if (empty($uri_id) && !empty($item_id)) { + $item = Post::selectFirst(['uri-id'], ['id' => $item_id]); + $uri_id = $item['uri-id'] ?? 0; + } + if (empty($uri_id)) { + $posts = Post\Delivery::selectForInbox($inbox); + $uri_ids = array_column($posts, 'uri-id'); + } else { + $uri_ids = [$uri_id]; + } + + foreach ($uri_ids as $uri_id) { + Post\Delivery::remove($uri_id, $inbox); + Post\DeliveryData::incrementQueueFailed($uri_id); } return; } @@ -79,7 +77,7 @@ class APDelivery $uri_ids = [$uri_id]; } - if (!$success && !Worker::defer() && in_array($cmd, [Delivery::POST])) { + if (!$success && !Worker::defer() && !empty($uri_ids)) { foreach ($uri_ids as $uri_id) { Post\Delivery::remove($uri_id, $inbox); Post\DeliveryData::incrementQueueFailed($uri_id); From a662245c744f4d2faa1b533977f7d21b4de6a724 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 May 2022 05:52:05 +0000 Subject: [PATCH 09/13] We now store the receivers as well --- database.sql | 1 + doc/database/db_post-delivery.md | 17 +++++++++-------- src/Model/Post/Delivery.php | 20 +++++++++++++++++--- src/Worker/APDelivery.php | 19 ++++--------------- src/Worker/Notifier.php | 4 ++-- static/dbstructure.config.php | 1 + 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/database.sql b/database.sql index 1508f358dc..d13a3330c2 100644 --- a/database.sql +++ b/database.sql @@ -1127,6 +1127,7 @@ CREATE TABLE IF NOT EXISTS `post-delivery` ( `created` datetime DEFAULT '0001-01-01 00:00:00' COMMENT '', `command` varbinary(32) COMMENT '', `failed` tinyint DEFAULT 0 COMMENT 'Number of times the delivery has failed', + `receivers` mediumtext COMMENT 'JSON encoded array with the receiving contacts', PRIMARY KEY(`uri-id`,`inbox-id`), INDEX `inbox-id_created` (`inbox-id`,`created`), INDEX `uid` (`uid`), diff --git a/doc/database/db_post-delivery.md b/doc/database/db_post-delivery.md index 8b149b5715..2a766eea56 100644 --- a/doc/database/db_post-delivery.md +++ b/doc/database/db_post-delivery.md @@ -6,14 +6,15 @@ Delivery data for posts for the batch processing Fields ------ -| Field | Description | Type | Null | Key | Default | Extra | -| -------- | --------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | ----- | -| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | | -| inbox-id | Item-uri id of inbox url | int unsigned | NO | PRI | NULL | | -| uid | Delivering user | mediumint unsigned | YES | | NULL | | -| created | | datetime | YES | | 0001-01-01 00:00:00 | | -| command | | varbinary(32) | YES | | NULL | | -| failed | Number of times the delivery has failed | tinyint | YES | | 0 | | +| Field | Description | Type | Null | Key | Default | Extra | +| --------- | --------------------------------------------------------- | ------------------ | ---- | --- | ------------------- | ----- | +| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | | +| inbox-id | Item-uri id of inbox url | int unsigned | NO | PRI | NULL | | +| uid | Delivering user | mediumint unsigned | YES | | NULL | | +| created | | datetime | YES | | 0001-01-01 00:00:00 | | +| command | | varbinary(32) | YES | | NULL | | +| failed | Number of times the delivery has failed | tinyint | YES | | 0 | | +| receivers | JSON encoded array with the receiving contacts | mediumtext | YES | | NULL | | Indexes ------------ diff --git a/src/Model/Post/Delivery.php b/src/Model/Post/Delivery.php index 8d19f8c941..52c1bf8e0e 100644 --- a/src/Model/Post/Delivery.php +++ b/src/Model/Post/Delivery.php @@ -35,14 +35,16 @@ class Delivery * @param integer $uri_id * @param string $inbox * @param string $created + * @param array %receivers */ - public static function add(int $uri_id, int $uid, string $inbox, string $created, string $command) + public static function add(int $uri_id, int $uid, string $inbox, string $created, string $command, array $receivers) { if (empty($uri_id)) { throw new BadMethodCallException('Empty URI_id'); } - $fields = ['uri-id' => $uri_id, 'uid' => $uid, 'inbox-id' => ItemURI::getIdByURI($inbox), 'created' => $created, 'command' => $command]; + $fields = ['uri-id' => $uri_id, 'uid' => $uid, 'inbox-id' => ItemURI::getIdByURI($inbox), + 'created' => $created, 'command' => $command, 'receivers' => json_encode($receivers)]; DBA::insert('post-delivery', $fields, Database::INSERT_IGNORE); } @@ -81,6 +83,18 @@ class Delivery public static function selectForInbox(string $inbox) { - return DBA::selectToArray('post-delivery', [], ['inbox-id' => ItemURI::getIdByURI($inbox)], ['order' => ['created']]); + $rows = DBA::select('post-delivery', [], ['inbox-id' => ItemURI::getIdByURI($inbox)], ['order' => ['created']]); + $deliveries = []; + while ($row = DBA::fetch($rows)) { + if (!empty($row['receivers'])) { + $row['receivers'] = json_decode($row['receivers'], true); + } else { + $row['receivers'] = []; + } + $deliveries[] = $row; + } + DBA::close($rows); + + return $deliveries; } } diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 641f27fce4..6995b0edf1 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -25,7 +25,6 @@ use Friendica\Core\Logger; use Friendica\Core\Worker; use Friendica\Model\Contact; use Friendica\Model\GServer; -use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Protocol\ActivityPub; use Friendica\Util\HTTPSignature; @@ -93,7 +92,7 @@ class APDelivery $posts = Post\Delivery::selectForInbox($inbox); foreach ($posts as $post) { - if (!self::deliverToInbox($post['command'], 0, $inbox, $post['uid'], [], $post['uri-id'])) { + if (!self::deliverToInbox($post['command'], 0, $inbox, $post['uid'], $post['receivers'], $post['uri-id'])) { $uri_ids[] = $post['uri-id']; } } @@ -106,22 +105,12 @@ class APDelivery { if (empty($item_id) && !empty($uri_id) && !empty($uid)) { $item = Post::selectFirst(['id', 'parent', 'origin'], ['uri-id' => $uri_id, 'uid' => [$uid, 0]], ['order' => ['uid' => true]]); - $item_id = $item['id'] ?? 0; - if (empty($receivers) && !empty($item)) { - $parent = Post::selectFirst(Item::DELIVER_FIELDLIST, ['id' => $item['parent']]); - - $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid); - $receivers = $inboxes[$inbox] ?? []; - - // When we haven't fetched the receiver list, it can be a personal inbox - if (empty($receivers)) { - $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid, true); - $receivers = $inboxes[$inbox] ?? []; - } - } elseif (empty($item_id)) { + if (empty($item['id'])) { Logger::debug('Item not found, removing delivery', ['uri-id' => $uri_id, 'uid' => $uid, 'cmd' => $cmd, 'inbox' => $inbox]); Post\Delivery::remove($uri_id, $inbox); return true; + } else { + $item_id = $item['id']; } } diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index 66c3cadbd1..e248c944dd 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -788,7 +788,7 @@ class Notifier if (DI::config()->get('system', 'bulk_delivery')) { $delivery_queue_count++; - Post\Delivery::add($target_item['uri-id'], $uid, $inbox, $target_item['created'], $cmd); + Post\Delivery::add($target_item['uri-id'], $uid, $inbox, $target_item['created'], $cmd, $receivers); Worker::add(PRIORITY_HIGH, 'APDelivery', '', 0, $inbox, 0); } else { if (Worker::add(['priority' => $priority, 'created' => $created, 'dont_fork' => true], @@ -804,7 +804,7 @@ class Notifier if (DI::config()->get('system', 'bulk_delivery')) { $delivery_queue_count++; - Post\Delivery::add($target_item['uri-id'], $uid, $inbox, $target_item['created'], $cmd); + Post\Delivery::add($target_item['uri-id'], $uid, $inbox, $target_item['created'], $cmd, []); Worker::add(PRIORITY_MEDIUM, 'APDelivery', '', 0, $inbox, 0); } else { if (Worker::add(['priority' => $priority, 'dont_fork' => true], 'APDelivery', $cmd, $target_item['id'], $inbox, $uid, [], $target_item['uri-id'])) { diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 101e3da343..44b2fc1f80 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -1166,6 +1166,7 @@ return [ "created" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => ""], "command" => ["type" => "varbinary(32)", "comment" => ""], "failed" => ["type" => "tinyint", "default" => 0, "comment" => "Number of times the delivery has failed"], + "receivers" => ["type" => "mediumtext", "comment" => "JSON encoded array with the receiving contacts"], ], "indexes" => [ "PRIMARY" => ["uri-id", "inbox-id"], From 0f0f4bc2c7fb5ab429f06ddc1202a138478f107a Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 May 2022 07:31:00 +0000 Subject: [PATCH 10/13] New worker job for deliveries without a worker --- src/Worker/Cron.php | 3 +++ src/Worker/RequeuePosts.php | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/Worker/RequeuePosts.php diff --git a/src/Worker/Cron.php b/src/Worker/Cron.php index 01c54fed18..e39ba24aae 100644 --- a/src/Worker/Cron.php +++ b/src/Worker/Cron.php @@ -95,6 +95,9 @@ class Cron // Clear cache entries Worker::add(PRIORITY_LOW, 'ClearCache'); + // Requeue posts from the post delivery entries + Worker::add(PRIORITY_MEDIUM, 'RequeuePosts'); + DI::config()->set('system', 'last_cron_hourly', time()); } diff --git a/src/Worker/RequeuePosts.php b/src/Worker/RequeuePosts.php new file mode 100644 index 0000000000..787e5b0710 --- /dev/null +++ b/src/Worker/RequeuePosts.php @@ -0,0 +1,44 @@ +. + * + */ + +namespace Friendica\Worker; + +use Friendica\Core\Logger; +use Friendica\Core\Worker; +use Friendica\Database\DBA; + +/** + * Requeue posts that are stuck in the post-delivery table without a matching delivery job. + * This should not happen in regular situations, this is a precaution. + */ +class RequeuePosts +{ + public static function execute() + { + $deliveries = DBA::p("SELECT `item-uri`.`uri` AS `inbox` FROM `post-delivery` INNER JOIN `item-uri` ON `item-uri`.`id` = `post-delivery`.`inbox-id` GROUP BY `inbox`"); + while ($delivery = DBA::fetch($deliveries)) { + if (Worker::add(PRIORITY_HIGH, 'APDelivery', '', 0, $delivery['inbox'], 0)) { + Logger::info('Missing APDelivery worker added for inbox', ['inbox' => $delivery['inbox']]); + } + } + DBA::close($deliveries); + } +} From 65b86fe0d556829c09e8c8f5c707b868ad37dfe1 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 May 2022 07:44:36 +0000 Subject: [PATCH 11/13] Blanks replaced --- src/Worker/RequeuePosts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Worker/RequeuePosts.php b/src/Worker/RequeuePosts.php index 787e5b0710..600a0d40b3 100644 --- a/src/Worker/RequeuePosts.php +++ b/src/Worker/RequeuePosts.php @@ -35,7 +35,7 @@ class RequeuePosts { $deliveries = DBA::p("SELECT `item-uri`.`uri` AS `inbox` FROM `post-delivery` INNER JOIN `item-uri` ON `item-uri`.`id` = `post-delivery`.`inbox-id` GROUP BY `inbox`"); while ($delivery = DBA::fetch($deliveries)) { - if (Worker::add(PRIORITY_HIGH, 'APDelivery', '', 0, $delivery['inbox'], 0)) { + if (Worker::add(PRIORITY_HIGH, 'APDelivery', '', 0, $delivery['inbox'], 0)) { Logger::info('Missing APDelivery worker added for inbox', ['inbox' => $delivery['inbox']]); } } From fab5ba39ff76dae9f7db17009b2ad146059c5439 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 May 2022 18:48:13 +0000 Subject: [PATCH 12/13] Failed post deliveries are now deleted via cron --- src/Model/Post/Delivery.php | 2 +- src/Worker/APDelivery.php | 2 -- src/Worker/RequeuePosts.php | 3 +++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Model/Post/Delivery.php b/src/Model/Post/Delivery.php index 52c1bf8e0e..f8ed068fe8 100644 --- a/src/Model/Post/Delivery.php +++ b/src/Model/Post/Delivery.php @@ -83,7 +83,7 @@ class Delivery public static function selectForInbox(string $inbox) { - $rows = DBA::select('post-delivery', [], ['inbox-id' => ItemURI::getIdByURI($inbox)], ['order' => ['created']]); + $rows = DBA::select('post-delivery', [], ["`inbox-id` = ? AND `failed` < ?", ItemURI::getIdByURI($inbox), DI::config()->get('system', 'worker_defer_limit')], ['order' => ['created']]); $deliveries = []; while ($row = DBA::fetch($rows)) { if (!empty($row['receivers'])) { diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php index 6995b0edf1..df9df8128a 100644 --- a/src/Worker/APDelivery.php +++ b/src/Worker/APDelivery.php @@ -86,8 +86,6 @@ class APDelivery private static function deliver(string $inbox) { - Post\Delivery::removeFailed($inbox); - $uri_ids = []; $posts = Post\Delivery::selectForInbox($inbox); diff --git a/src/Worker/RequeuePosts.php b/src/Worker/RequeuePosts.php index 600a0d40b3..3c3d249bb6 100644 --- a/src/Worker/RequeuePosts.php +++ b/src/Worker/RequeuePosts.php @@ -24,6 +24,7 @@ namespace Friendica\Worker; use Friendica\Core\Logger; use Friendica\Core\Worker; use Friendica\Database\DBA; +use Friendica\Model\Post; /** * Requeue posts that are stuck in the post-delivery table without a matching delivery job. @@ -35,6 +36,8 @@ class RequeuePosts { $deliveries = DBA::p("SELECT `item-uri`.`uri` AS `inbox` FROM `post-delivery` INNER JOIN `item-uri` ON `item-uri`.`id` = `post-delivery`.`inbox-id` GROUP BY `inbox`"); while ($delivery = DBA::fetch($deliveries)) { + Post\Delivery::removeFailed($delivery['inbox']); + if (Worker::add(PRIORITY_HIGH, 'APDelivery', '', 0, $delivery['inbox'], 0)) { Logger::info('Missing APDelivery worker added for inbox', ['inbox' => $delivery['inbox']]); } From 4ef2679ca675bd3c80ccf8b21346bebf5996e762 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 13 May 2022 19:37:50 +0000 Subject: [PATCH 13/13] Fix test --- src/Worker/RequeuePosts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Worker/RequeuePosts.php b/src/Worker/RequeuePosts.php index 3c3d249bb6..568595aafd 100644 --- a/src/Worker/RequeuePosts.php +++ b/src/Worker/RequeuePosts.php @@ -37,7 +37,7 @@ class RequeuePosts $deliveries = DBA::p("SELECT `item-uri`.`uri` AS `inbox` FROM `post-delivery` INNER JOIN `item-uri` ON `item-uri`.`id` = `post-delivery`.`inbox-id` GROUP BY `inbox`"); while ($delivery = DBA::fetch($deliveries)) { Post\Delivery::removeFailed($delivery['inbox']); - + if (Worker::add(PRIORITY_HIGH, 'APDelivery', '', 0, $delivery['inbox'], 0)) { Logger::info('Missing APDelivery worker added for inbox', ['inbox' => $delivery['inbox']]); }