From 147ade1b579183967605e41260a1f2b374d0df2f Mon Sep 17 00:00:00 2001 From: gravel Date: Thu, 1 Jun 2023 16:43:17 +0200 Subject: [PATCH] Fetch assets in parallel --- php/utils/fetching-coroutines.php | 2 +- php/utils/room-icons.php | 45 +++++++++++++++++------ php/utils/room-invites.php | 22 ++++++++--- php/utils/servers-rooms.php | 32 +++++++++++++--- sites/+components/communities-json-ld.php | 2 +- sites/index.php | 3 ++ 6 files changed, 81 insertions(+), 25 deletions(-) diff --git a/php/utils/fetching-coroutines.php b/php/utils/fetching-coroutines.php index bbc5576..889929a 100644 --- a/php/utils/fetching-coroutines.php +++ b/php/utils/fetching-coroutines.php @@ -272,7 +272,7 @@ * Launches all coroutines in parallel. * @return int CURLM_* status. */ - public function fetch_all(): int { + public function run_all(): int { do { $curlm_status = curl_multi_exec($this->transfers, $curlm_active_transfer); if ($curlm_active_transfer) { diff --git a/php/utils/room-icons.php b/php/utils/room-icons.php index feade44..6e39e28 100644 --- a/php/utils/room-icons.php +++ b/php/utils/room-icons.php @@ -31,22 +31,15 @@ } /** - * Fetch the icon of the given room and return its relative path. - * @param \CommunityRoom $room - * @param string $size Image dimensions. - * @return string Relative path or null if icon is absent. + * @return \Generator */ - function room_icon(\CommunityRoom $room, string $size): ?string { - list($width, $height) = explode("x", $size); - $width = intval($width); - $height = intval($height); - assert(!empty($width) && !empty($height)); + function fetch_room_icon_coroutine(\CommunityRoom $room): Generator { if (room_icon_safety($room) < 0) { - return null; + return; } + $room_id = $room->get_room_identifier(); $icon_cached = room_icon_path($room_id); - $icon_resized = room_icon_path_resized($room_id, $size); $icon_expired = file_exists($icon_cached) && filemtime($icon_cached) < strtotime("-1 day"); // Re-fetch icons periodically. @@ -56,7 +49,8 @@ return null; } log_debug("Fetching icon for $room_id."); - $icon = file_get_contents($icon_url); + $icon_response = yield from FetchingCoroutine::from_url($icon_url)->run(); + $icon = $icon_response ? curl_multi_getcontent($icon_response) : null; if (empty($icon)) { log_info("$room_id returned an empty icon."); } @@ -65,6 +59,33 @@ file_put_contents($icon_cached, $icon); } } + } + + /** + * Fetch the icon of the given room and return its relative path. + * @param \CommunityRoom $room + * @param string $size Image dimensions. + * @return string Relative path or null if icon is absent. + */ + function room_icon(\CommunityRoom $room, string $size): ?string { + list($width, $height) = explode("x", $size); + $width = intval($width); + $height = intval($height); + assert(!empty($width) && !empty($height)); + + if (room_icon_safety($room) < 0) { + return null; + } + + $room_id = $room->get_room_identifier(); + $icon_cached = room_icon_path($room_id); + $icon_resized = room_icon_path_resized($room_id, $size); + $icon_expired = file_exists($icon_cached) && filemtime($icon_cached) < strtotime("-1 day"); + + if (!file_exists($icon_cached)) { + log_debug("Missing icon asset for $room_id"); + return ""; + } if (!file_exists($icon_resized) || $icon_expired) { $icon_cached_contents = file_get_contents($icon_cached); if (empty($icon_cached_contents)) { diff --git a/php/utils/room-invites.php b/php/utils/room-invites.php index 9b921e1..50ab8e0 100644 --- a/php/utils/room-invites.php +++ b/php/utils/room-invites.php @@ -19,11 +19,9 @@ /** - * Fetch QR invite of the given room and return its relative path. - * @param \CommunityRoom $room - * @return string + * @return \Generator */ - function room_qr_code($room): string { + function fetch_qr_code_coroutine(\CommunityRoom $room): Generator { $room_id = $room->get_room_identifier(); $png_cached = room_qr_code_path($room_id); $image_expired = file_exists($png_cached) && @@ -32,7 +30,8 @@ return room_qr_code_path_relative($room_id); } log_debug("Fetching QR code for $room_id."); - $png = file_get_contents($room->get_invite_url()); + $png_response = yield from FetchingCoroutine::from_url($room->get_invite_url())->run(); + $png = $png_response ? curl_multi_getcontent($png_response) : null; if (empty($png)) { log_warning("$room_id returned an empty QR code."); } @@ -40,6 +39,19 @@ if (!(file_exists($png_cached) && filesize($png_cached) > 0 && empty($png))) { file_put_contents($png_cached, $png); } + } + + /** + * Fetch QR invite of the given room and return its relative path. + * @param \CommunityRoom $room + * @return string + */ + function room_qr_code(\CommunityRoom $room): string { + $room_id = $room->get_room_identifier(); + if (!file_exists(room_qr_code_path($room_id))) { + log_warning("Missing QR code asset for $room_id."); + return ""; + } return room_qr_code_path_relative($room_id); } diff --git a/php/utils/servers-rooms.php b/php/utils/servers-rooms.php index 414e50b..108ed2f 100644 --- a/php/utils/servers-rooms.php +++ b/php/utils/servers-rooms.php @@ -1,9 +1,11 @@ fetch_all(); + $runner->run_all(); return $reachable_servers; } @@ -918,8 +920,9 @@ foreach ($this->room_hints as $token) { log_debug("Testing room /$token at $base_url."); - // FIXME: This fetches room hints sequentially per each server + // Note: This fetches room hints sequentially per each server // Would need to allow yielding handle arrays + // More than good enough for now $room_api_response = yield from FetchingCoroutine ::from_url($this->get_room_api_url($token)) @@ -1082,6 +1085,23 @@ return true; } + /** + * @param \CommunityServer $servers + */ + public static function fetch_assets(array $servers) { + // Sequential in each server, see note in fetch_room_hints_coroutine() + $coroutines = []; + + foreach (CommunityServer::enumerate_rooms($servers) as $room) { + $coroutines[] = new FetchingCoroutine((function() use ($room) { + yield from fetch_qr_code_coroutine($room); + yield from fetch_room_icon_coroutine($room); + })()); + } + + (new FetchingCoroutineRunner($coroutines))->run_all(); + } + /** * Checks whether this server belongs to Session / OPTF. */ diff --git a/sites/+components/communities-json-ld.php b/sites/+components/communities-json-ld.php index 437837f..593e22c 100644 --- a/sites/+components/communities-json-ld.php +++ b/sites/+components/communities-json-ld.php @@ -1,5 +1,5 @@