timeout direct upload control requests
This commit is contained in:
parent
2b875847dd
commit
81a0b29633
@ -7,6 +7,8 @@ const SERVER_UPLOAD_MAX_BYTES = 50 * 1024 * 1024;
|
||||
const DIRECT_UPLOAD_PART_CONCURRENCY = 4;
|
||||
const DIRECT_UPLOAD_SUPPRESS_MS = 2 * 60 * 1000;
|
||||
const CLIENT_UPLOAD_ID_FIELD = "clientUploadId";
|
||||
const DIRECT_UPLOAD_ACTION_TIMEOUT_MS = 15 * 1000;
|
||||
const DIRECT_UPLOAD_ABORT_TIMEOUT_MS = 8 * 1000;
|
||||
const XHR_UPLOAD_TOTAL_TIMEOUT_MS = 6 * 60 * 1000;
|
||||
const XHR_UPLOAD_STALL_TIMEOUT_MS = 30 * 1000;
|
||||
|
||||
@ -90,6 +92,12 @@ function createAbortError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
function createTimeoutError(message: string) {
|
||||
const error = new Error(message);
|
||||
error.name = "TimeoutError";
|
||||
return error;
|
||||
}
|
||||
|
||||
function sleep(ms: number, signal?: AbortSignal) {
|
||||
if (signal?.aborted) {
|
||||
return Promise.reject(createAbortError());
|
||||
@ -314,18 +322,75 @@ async function readErrorPayload(response: Response) {
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchWithControlTimeout(
|
||||
input: RequestInfo | URL,
|
||||
init: RequestInit,
|
||||
timeoutMs: number,
|
||||
signal?: AbortSignal
|
||||
) {
|
||||
if (signal?.aborted) {
|
||||
throw createAbortError();
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
let timeout: ReturnType<typeof setTimeout> | null = null;
|
||||
let timedOut = false;
|
||||
|
||||
const onAbort = () => {
|
||||
controller.abort();
|
||||
};
|
||||
|
||||
signal?.addEventListener("abort", onAbort, { once: true });
|
||||
|
||||
try {
|
||||
timeout = setTimeout(() => {
|
||||
timedOut = true;
|
||||
controller.abort();
|
||||
}, timeoutMs);
|
||||
|
||||
return await fetch(input, {
|
||||
...init,
|
||||
signal: controller.signal,
|
||||
});
|
||||
} catch (error) {
|
||||
if (signal?.aborted) {
|
||||
throw createAbortError();
|
||||
}
|
||||
|
||||
if (timedOut) {
|
||||
throw createTimeoutError(
|
||||
`Direct upload control request timed out after ${Math.round(
|
||||
timeoutMs / 1000
|
||||
)}s`
|
||||
);
|
||||
}
|
||||
|
||||
throw error;
|
||||
} finally {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
signal?.removeEventListener("abort", onAbort);
|
||||
}
|
||||
}
|
||||
|
||||
async function postDirectUploadAction<T>(
|
||||
payload: Record<string, unknown>,
|
||||
signal?: AbortSignal
|
||||
signal?: AbortSignal,
|
||||
timeoutMs = DIRECT_UPLOAD_ACTION_TIMEOUT_MS
|
||||
): Promise<T> {
|
||||
const response = await fetch("/api/files/direct-upload", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
const response = await fetchWithControlTimeout(
|
||||
"/api/files/direct-upload",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
signal,
|
||||
});
|
||||
timeoutMs,
|
||||
signal
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(String(await readErrorPayload(response)));
|
||||
@ -745,7 +810,8 @@ async function fetchDirectUpload(
|
||||
uploadId: multipartUpload.uploadId,
|
||||
clientUploadId: file.clientUploadId,
|
||||
},
|
||||
signal
|
||||
signal,
|
||||
DIRECT_UPLOAD_ABORT_TIMEOUT_MS
|
||||
).catch(() => {});
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user