perf(canvas): reuse durable prepared PNGs in batch and fallback downloads
This commit is contained in:
parent
425d3a4ddf
commit
dfc1c6d496
@ -303,6 +303,20 @@ export async function fetchCanvasDownloadAsset(params: {
|
||||
params.requestOrigin
|
||||
);
|
||||
|
||||
if (process.env.POSTGRES_URL) {
|
||||
// ZIPs and binary fallback also reuse the durable prepared object after the
|
||||
// local byte cache expires, instead of converting the original JPEG again.
|
||||
const { findImageArchiveDownloadTask } = await import("@/lib/storage/image-archive-db");
|
||||
const task = await findImageArchiveDownloadTask(candidateUrls).catch(() => null);
|
||||
const asset = (task?.metadata as { downloadAsset?: { status?: string; url?: string; contentType?: string } } | null)?.downloadAsset;
|
||||
if (asset?.status === "ready" && asset.url && asset.contentType === "image/png") {
|
||||
const readyUrl = resolveHttpUrl(asset.url, params.requestOrigin);
|
||||
if (readyUrl && !candidateUrls.includes(readyUrl)) candidateUrls.unshift(readyUrl);
|
||||
} else if (task?.targetUrl && !candidateUrls.includes(task.targetUrl)) {
|
||||
candidateUrls.unshift(task.targetUrl);
|
||||
}
|
||||
}
|
||||
|
||||
for (const candidateUrl of candidateUrls) {
|
||||
for (let attempt = 1; attempt <= retryCount; attempt += 1) {
|
||||
try {
|
||||
|
||||
@ -8,7 +8,7 @@ export async function resolveCanvasCdnDownload(urls: string[], filename: string)
|
||||
const source = extractImageProxySourceUrl(url) || url;
|
||||
return [source, inferOriginalImageUrl(source) || source];
|
||||
})));
|
||||
const task = await findImageArchiveDownloadTask(sources);
|
||||
const task = await findImageArchiveDownloadTask(sources, true);
|
||||
const asset = (task?.metadata as { downloadAsset?: { status?: string; url?: string; contentType?: string; bytes?: number } } | null)?.downloadAsset;
|
||||
if (asset?.status !== "ready" || !asset.url || asset.contentType !== "image/png") return { task, direct: null };
|
||||
const config = await getDefaultStorageConfig();
|
||||
|
||||
@ -317,11 +317,11 @@ export async function resolveArchivedImageUrls<T>(value: T): Promise<T> {
|
||||
|
||||
// Download assets use an independent JSONB lease; original archiving/replacement
|
||||
// can finish even if PNG preparation or thumbnail storage is temporarily unavailable.
|
||||
export async function findImageArchiveDownloadTask(urls: string[]) {
|
||||
export async function findImageArchiveDownloadTask(urls: string[], prepareOnDemand = false) {
|
||||
const [task] = await db.select().from(imageArchiveTask).where(or(
|
||||
inArray(imageArchiveTask.sourceUrl, urls), inArray(imageArchiveTask.targetUrl, urls),
|
||||
)).limit(1);
|
||||
if (task?.targetUrl && !(task.metadata as { downloadAsset?: unknown } | null)?.downloadAsset) {
|
||||
if (prepareOnDemand && task?.targetUrl && !(task.metadata as { downloadAsset?: unknown } | null)?.downloadAsset) {
|
||||
await db.update(imageArchiveTask).set({
|
||||
metadata: sql`coalesce(${imageArchiveTask.metadata}, '{}'::jsonb) || jsonb_build_object('downloadAsset', jsonb_build_object('status', 'pending'))`,
|
||||
}).where(and(eq(imageArchiveTask.id, task.id), sql`${imageArchiveTask.metadata}->'downloadAsset' is null`));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user