From e6b446c95f8f52aaedef94d2a2126f5b34043e39 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Fri, 25 Apr 2025 14:50:30 +0530 Subject: [PATCH] Cont --- desktop/src/main/stream.ts | 50 +++++++++++-------- web/apps/photos/src/services/upload/remote.ts | 2 +- web/packages/base/http.ts | 2 +- web/packages/gallery/services/video.ts | 6 +-- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/desktop/src/main/stream.ts b/desktop/src/main/stream.ts index db7cae901a..b5c239d27f 100644 --- a/desktop/src/main/stream.ts +++ b/desktop/src/main/stream.ts @@ -298,20 +298,25 @@ const handleGenerateHLSWrite = async ( inputTempFilePath, outputFilePathPrefix, ); + + const videoFilePath = result.videoPath; + try { + await uploadVideoSegments(videoFilePath, objectUploadURL); + + const playlistToken = randomUUID(); + pendingVideoResults.set(playlistToken, result.playlistPath); + + const { dimensions, videoSize } = result; + return new Response( + JSON.stringify({ playlistToken, dimensions, videoSize }), + { status: 200 }, + ); + } finally { + await deleteTempFileIgnoringErrors(videoFilePath); + } } finally { await deleteTempFileIgnoringErrors(inputTempFilePath); } - - await uploadVideoSegments(result.videoPath, objectUploadURL); - - const playlistToken = randomUUID(); - pendingVideoResults.set(playlistToken, result.playlistPath); - - const { dimensions, videoSize } = result; - return new Response( - JSON.stringify({ playlistToken, dimensions, videoSize }), - { status: 200 }, - ); }; /** @@ -324,21 +329,20 @@ const handleGenerateHLSWrite = async ( * * --- * - * This is an inlined reimplementation of `retryEnsuringHTTPOkOr4xx` from - * `web/packages/base/http.ts`. + * This is an inlined but bespoke reimplementation of `retryEnsuringHTTPOkOr4xx` + * from `web/packages/base/http.ts` (we don't have the rest of the scaffolding + * used by that function, which is why it is inlined bespoked). * - * It is included here for the specific use of uploading videos since generating - * the HLS stream is a fairly expensive operation, so a retry to discount - * transient network issues is called for. - * - * We don't currently have rest of the scaffolding used by - * `retryEnsuringHTTPOkOr4xx`, which is why we just inline it bespoke. + * It handles the specific use case of uploading videos since generating the HLS + * stream is a fairly expensive operation, so a retry to discount transient + * network issues is called for. There are only 2 retries for a total of 3 + * attempts, and the retry gaps are more spaced out. */ export const uploadVideoSegments = async ( videoFilePath: string, objectUploadURL: string, ) => { - const waitTimeBeforeNextTry = [2000, 5000, 10000]; + const waitTimeBeforeNextTry = [5000, 20000]; while (true) { let abort = false; @@ -350,10 +354,12 @@ export const uploadVideoSegments = async ( }); if (res.ok) { - /* success */ return; + // Success. + return; } if (res.status >= 400 && res.status < 500) { - abort = true; /* 4xx */ + // HTTP 4xx. + abort = true; } throw new Error( `Failed to upload generated HLS video: HTTP ${res.status} ${res.statusText}`, diff --git a/web/apps/photos/src/services/upload/remote.ts b/web/apps/photos/src/services/upload/remote.ts index 8d92d42a49..632532e5c0 100644 --- a/web/apps/photos/src/services/upload/remote.ts +++ b/web/apps/photos/src/services/upload/remote.ts @@ -2,6 +2,7 @@ import { authenticatedPublicAlbumsRequestHeaders, authenticatedRequestHeaders, ensureOk, + retryAsyncOperation, type PublicAlbumsCredentials, } from "ente-base/http"; import log from "ente-base/log"; @@ -10,7 +11,6 @@ import { EnteFile } from "ente-media/file"; import { CustomError, handleUploadError } from "ente-shared/error"; import HTTPService from "ente-shared/network/HTTPService"; import { getToken } from "ente-shared/storage/localStorage/helpers"; -import { retryAsyncOperation } from "ente-base/http"; import { z } from "zod"; import { MultipartUploadURLs, UploadFile } from "./upload-service"; diff --git a/web/packages/base/http.ts b/web/packages/base/http.ts index 10eca5ba96..6a12185c56 100644 --- a/web/packages/base/http.ts +++ b/web/packages/base/http.ts @@ -195,7 +195,7 @@ export const retryAsyncOperation = async ( } const t = waitTimeBeforeNextTry.shift(); if (!t) throw e; - log.info("Will retry potentially transient request failure", e); + log.warn("Will retry potentially transient request failure", e); await wait(t); } } diff --git a/web/packages/gallery/services/video.ts b/web/packages/gallery/services/video.ts index 760e7408c2..a0fc763b32 100644 --- a/web/packages/gallery/services/video.ts +++ b/web/packages/gallery/services/video.ts @@ -403,7 +403,7 @@ const processQueueItem = async ( const { objectID, url: objectUploadURL } = await getFilePreviewDataUploadURL(file); - log.info(`HLS gen ${fileLogID(file)} | start`); + log.info(`Generate HLS for ${fileLogID(file)} | start`); // [Note: Upload HLS video segment from node side] // @@ -419,7 +419,7 @@ const processQueueItem = async ( // // So instead we provide the presigned upload URL to the node side so that // it can directly upload the generated video segments. - const queryParams = new URLSearchParams(objectUploadURL); + const queryParams = new URLSearchParams({ objectUploadURL }); const res = await writeVideoStream( electron, @@ -446,7 +446,7 @@ const processQueueItem = async ( await putVideoData(file, playlistData, objectID, videoSize); - log.info(`HLS gen ${fileLogID(file)} | done`); + log.info(`Generate HLS for ${fileLogID(file)} | done`); } finally { await Promise.all([videoStreamDone(electron, playlistToken)]); }