fix: queue image resizing
This commit is contained in:
@ -7,9 +7,16 @@ import {
|
||||
import { parseMediaType } from "https://deno.land/std@0.175.0/media_types/parse_media_type.ts";
|
||||
import * as cache from "@lib/cache/image.ts";
|
||||
import { SILVERBULLET_SERVER } from "@lib/env.ts";
|
||||
import { PromiseQueue } from "@lib/promise.ts";
|
||||
import { BadRequestError } from "@lib/errors.ts";
|
||||
|
||||
await initialize();
|
||||
|
||||
type ImageParams = {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
async function getRemoteImage(image: string) {
|
||||
console.log("[api/image] fetching", { image });
|
||||
const sourceRes = await fetch(image);
|
||||
@ -35,8 +42,8 @@ function getWidthHeight(
|
||||
: (current.width / final.width);
|
||||
|
||||
return new MagickGeometry(
|
||||
current.width / ratio,
|
||||
current.height / ratio,
|
||||
Math.floor(current.width / ratio),
|
||||
Math.floor(current.height / ratio),
|
||||
);
|
||||
}
|
||||
|
||||
@ -82,6 +89,35 @@ function parseParams(reqUrl: URL) {
|
||||
};
|
||||
}
|
||||
|
||||
const queue = new PromiseQueue();
|
||||
|
||||
async function processImage(imageUrl: string, params: ImageParams) {
|
||||
const remoteImage = await getRemoteImage(imageUrl);
|
||||
if (typeof remoteImage === "string") {
|
||||
console.log("[api/image] ERROR " + remoteImage);
|
||||
throw new BadRequestError();
|
||||
}
|
||||
|
||||
const modifiedImage = await modifyImage(remoteImage.buffer, {
|
||||
...params,
|
||||
mode: "resize",
|
||||
});
|
||||
|
||||
console.log("[api/image] resized image", {
|
||||
imageUrl,
|
||||
length: modifiedImage.length,
|
||||
});
|
||||
|
||||
await cache.setImage(modifiedImage.slice(), {
|
||||
url: imageUrl,
|
||||
width: params.width,
|
||||
height: params.height,
|
||||
mediaType: remoteImage.mediaType,
|
||||
});
|
||||
|
||||
return [modifiedImage, remoteImage.mediaType] as const;
|
||||
}
|
||||
|
||||
const GET = async (
|
||||
_req: Request,
|
||||
_ctx: HandlerContext,
|
||||
@ -113,35 +149,13 @@ const GET = async (
|
||||
console.log("[api/image] no image in cache");
|
||||
}
|
||||
|
||||
const remoteImage = await getRemoteImage(imageUrl);
|
||||
if (typeof remoteImage === "string") {
|
||||
console.log("[api/image] ERROR " + remoteImage);
|
||||
return new Response(remoteImage, { status: 400 });
|
||||
}
|
||||
const [resizedImage, mediaType] = await queue.enqueue(() =>
|
||||
processImage(imageUrl, params)
|
||||
);
|
||||
|
||||
const modifiedImage = await modifyImage(remoteImage.buffer, {
|
||||
...params,
|
||||
mode: "resize",
|
||||
});
|
||||
|
||||
console.log("[api/image] resized image", { imageUrl });
|
||||
|
||||
await cache.setImage(modifiedImage, {
|
||||
url: imageUrl,
|
||||
width: params.width,
|
||||
height: params.height,
|
||||
mediaType: remoteImage.mediaType,
|
||||
});
|
||||
|
||||
const cachedImage = await cache.getImage({
|
||||
url: imageUrl,
|
||||
width: params.width,
|
||||
height: params.height,
|
||||
});
|
||||
|
||||
return new Response(cachedImage.data || modifiedImage, {
|
||||
return new Response(resizedImage, {
|
||||
headers: {
|
||||
"Content-Type": remoteImage.mediaType,
|
||||
"Content-Type": mediaType,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
Reference in New Issue
Block a user