feat: a ton of caching
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"dev": "bun run --watch src/index.ts",
|
"dev": "bun run --hot src/index.ts",
|
||||||
"build": "bun build.ts"
|
"build": "bun build.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+8
-6
@@ -2,8 +2,16 @@ import cluster from "node:cluster";
|
|||||||
import process from "node:process";
|
import process from "node:process";
|
||||||
import { AssetManager } from "./lib/assets";
|
import { AssetManager } from "./lib/assets";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
var forked: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (cluster.isPrimary) {
|
if (cluster.isPrimary) {
|
||||||
|
if (!globalThis.forked) {
|
||||||
for (let i = 0; i < 2; i++) cluster.fork();
|
for (let i = 0; i < 2; i++) cluster.fork();
|
||||||
|
globalThis.forked = true;
|
||||||
|
}
|
||||||
|
|
||||||
queueMicrotask(async () => {
|
queueMicrotask(async () => {
|
||||||
const assets = new AssetManager();
|
const assets = new AssetManager();
|
||||||
@@ -13,12 +21,6 @@ if (cluster.isPrimary) {
|
|||||||
assets.getMissingAssets();
|
assets.getMissingAssets();
|
||||||
}, 86400000); // refresh assets every 24 hours
|
}, 86400000); // refresh assets every 24 hours
|
||||||
});
|
});
|
||||||
|
|
||||||
import.meta.hot.dispose(() => {
|
|
||||||
for (const worker of Object.values(cluster.workers ?? {})) {
|
|
||||||
worker?.kill();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
await import("./server");
|
await import("./server");
|
||||||
console.log(`Worker ${process.pid} started`);
|
console.log(`Worker ${process.pid} started`);
|
||||||
|
|||||||
@@ -54,6 +54,39 @@ export class AssetManager {
|
|||||||
queueMicrotask(() => write(local, data));
|
queueMicrotask(() => write(local, data));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async hook(
|
||||||
|
path: string,
|
||||||
|
cb: (
|
||||||
|
data: ArrayBuffer,
|
||||||
|
) => Promise<ArrayBuffer | Buffer> | ArrayBuffer | Buffer,
|
||||||
|
): Promise<ArrayBuffer | Buffer> {
|
||||||
|
const key = `${path}-transformed`;
|
||||||
|
return this.fnCache(key, async () => {
|
||||||
|
const data = await this.load(path);
|
||||||
|
return cb(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fnCache(
|
||||||
|
key: string,
|
||||||
|
get: () => Promise<ArrayBuffer | Buffer> | ArrayBuffer | Buffer,
|
||||||
|
) {
|
||||||
|
const cacheKey = join("store", hash(`${key}-fnCache`).toString(36));
|
||||||
|
if (this.cache.has(cacheKey)) return this.cache.get(cacheKey)!;
|
||||||
|
const cached = file(cacheKey);
|
||||||
|
if (await cached.exists()) return cached.arrayBuffer();
|
||||||
|
|
||||||
|
const returned = await get();
|
||||||
|
this.cache.set(
|
||||||
|
cacheKey,
|
||||||
|
returned instanceof ArrayBuffer
|
||||||
|
? returned
|
||||||
|
: (returned.buffer as ArrayBuffer),
|
||||||
|
);
|
||||||
|
queueMicrotask(() => write(file(cacheKey), returned));
|
||||||
|
return returned;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getEnkaAvatarStore(): Promise<AvatarStore> {
|
export async function getEnkaAvatarStore(): Promise<AvatarStore> {
|
||||||
|
|||||||
+10
-5
@@ -68,23 +68,28 @@ export function card(app: App) {
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
assets
|
assets
|
||||||
.load(
|
.hook(
|
||||||
avatar.SideIconName.replace(
|
avatar.SideIconName.replace(
|
||||||
"AvatarIcon_Side",
|
"AvatarIcon_Side",
|
||||||
"Gacha_AvatarImg",
|
"Gacha_AvatarImg",
|
||||||
),
|
),
|
||||||
|
(buf) => featherImage(buf, [0, 0.3, 0, 0]),
|
||||||
)
|
)
|
||||||
.then(async (buf) => ({
|
.then(async (data) => ({
|
||||||
src: "/avatar",
|
src: "/avatar",
|
||||||
data: await featherImage(buf, [0, 0.3, 0, 0]),
|
data,
|
||||||
})),
|
})),
|
||||||
|
assets
|
||||||
|
.fnCache("bg", () =>
|
||||||
generateBackground({
|
generateBackground({
|
||||||
element: avatar.Element,
|
element: avatar.Element,
|
||||||
width: 1218,
|
width: 1218,
|
||||||
height: 508,
|
height: 508,
|
||||||
}).then((r) => ({
|
}).then((r) => r.canvas.toBuffer("image/webp")),
|
||||||
|
)
|
||||||
|
.then((data) => ({
|
||||||
src: "/bg",
|
src: "/bg",
|
||||||
data: r.canvas.toBuffer("image/webp"),
|
data,
|
||||||
})),
|
})),
|
||||||
]);
|
]);
|
||||||
console.log(
|
console.log(
|
||||||
|
|||||||
Reference in New Issue
Block a user