From 1bc9ebafadb1a8c81a4c00e2c731c0a8d24b525e Mon Sep 17 00:00:00 2001 From: XLor Date: Sat, 12 Aug 2023 00:26:34 +0800 Subject: [PATCH] feat(worker): prefetch resources after cache --- packages/worker/package.json | 1 + packages/worker/src/query.ts | 26 ++++++++++++++------------ packages/worker/src/scheduled.ts | 7 +++++++ pnpm-lock.yaml | 7 +++++++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/packages/worker/package.json b/packages/worker/package.json index f26b1e30..520f2ba5 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -18,6 +18,7 @@ "anitomy": "workspace:*", "hono": "^3.4.1", "memofunc": "^0.0.5", + "ohash": "^1.1.3", "simptrad": "^0.1.0" }, "devDependencies": { diff --git a/packages/worker/src/query.ts b/packages/worker/src/query.ts index c606b4b6..ce8fda68 100644 --- a/packages/worker/src/query.ts +++ b/packages/worker/src/query.ts @@ -1,6 +1,7 @@ import type { Context } from 'hono'; import type { Resource, Team, User } from '@prisma/client/edge'; +import { hash } from 'ohash'; import { memoAsync } from 'memofunc'; import { parseSearchURL, @@ -36,7 +37,13 @@ export async function queryResourceDetail(ctx: Context<{ Bindings: Env }>) { return ctx.json({ detail }); } -export const getSearchResources = memoAsync( +export const PrefetchFilter = [ + parseSearchURL(new URLSearchParams('?page=1')), + parseSearchURL(new URLSearchParams('?page=2')), + parseSearchURL(new URLSearchParams('?page=3')) +]; + +export const findResourcesFromDB = memoAsync( async (env: Env, options: ResolvedFilterOptions) => { const prisma = makePrisma(env); @@ -118,26 +125,21 @@ export const getSearchResources = memoAsync( { external: { async get([env, params]) { - return getResourcesStore(env).get(JSON.stringify({ params })); + return getResourcesStore(env).get(hash(params)); }, async set([env, params], value) { - return getResourcesStore(env).put(JSON.stringify({ params }), value, { + return getResourcesStore(env).put(hash(params), value, { expirationTtl: 300 }); }, async remove([env, params]) { - return getResourcesStore(env).remove(JSON.stringify({ params })); + return getResourcesStore(env).remove(hash(params)); }, async clear() {} } } ); -async function getTimestamp(ctx: Context<{ Bindings: Env }>) { - const timestamp = await getRefreshTimestamp(ctx.env); - return timestamp; -} - export async function searchResources(ctx: Context<{ Bindings: Env }>) { const url = new URL(ctx.req.url); const filter = parseSearchURL(url.searchParams, await ctx.req.json().catch(() => undefined)); @@ -145,11 +147,11 @@ export async function searchResources(ctx: Context<{ Bindings: Env }>) { return ctx.json({ message: 'Request is not valid' }, 400); } - const timestampPromise = getTimestamp(ctx); + const timestampPromise = getRefreshTimestamp(ctx.env); const result = !isNoCache(ctx) - ? await getSearchResources(ctx.env, filter) - : await getSearchResources.raw(ctx.env, filter); + ? await findResourcesFromDB(ctx.env, filter) + : await findResourcesFromDB.raw(ctx.env, filter); const complete = result.length > filter.pageSize; const resources = resolveQueryResult(result.slice(0, filter.pageSize)); diff --git a/packages/worker/src/scheduled.ts b/packages/worker/src/scheduled.ts index 32076c2c..76c0d26b 100644 --- a/packages/worker/src/scheduled.ts +++ b/packages/worker/src/scheduled.ts @@ -7,6 +7,7 @@ import type { Env } from './types'; import { makePrisma } from './prisma'; import { updateRefreshTimestamp } from './state'; +import { findResourcesFromDB, PrefetchFilter } from './query'; const teams = new Set(); const users = new Set(); @@ -73,6 +74,12 @@ export async function handleScheduled(env: Env) { if (sum > 0) { await updateRefreshTimestamp(env); + await Promise.all( + PrefetchFilter.map(async (filter) => { + await findResourcesFromDB.clear(env, filter); + await findResourcesFromDB(env, filter); + }) + ); } return { count: sum }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb00f79a..9c7a2082 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -193,6 +193,9 @@ importers: memofunc: specifier: ^0.0.5 version: 0.0.5 + ohash: + specifier: ^1.1.3 + version: 1.1.3 simptrad: specifier: ^0.1.0 version: 0.1.0 @@ -4407,6 +4410,10 @@ packages: resolution: {integrity: sha512-9CIOSq5945rI045GFtcO3uudyOkYVY1nyfFxVQp+9BRgslr8jPNiSSrsFGg/BNTUFOLqx0P5tng6G32brIPw0w==} dev: true + /ohash@1.1.3: + resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: