This commit is contained in:
Manav Rathi
2025-04-25 14:50:30 +05:30
parent a2debd6746
commit e6b446c95f
4 changed files with 33 additions and 27 deletions

View File

@@ -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}`,

View File

@@ -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";

View File

@@ -195,7 +195,7 @@ export const retryAsyncOperation = async <T>(
}
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);
}
}

View File

@@ -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)]);
}