mirror of
https://github.com/massbug/judge4c.git
synced 2025-05-17 23:12:23 +00:00
feat(prisma): add server-only caching for problems queries
- Add 'server-only' import to enforce server-side usage - Implement cached problem queries with logging: - Add getProblems/getCachedProblems for all problems - Add getProblem/getCachedProblem for single problem by ID - Use React cache and Next.js unstable_cache with tags - Add detailed logging with timing metrics
This commit is contained in:
parent
aed942e7e2
commit
2c7223a323
@ -1,5 +1,12 @@
|
||||
import "server-only";
|
||||
|
||||
import { cache } from "react";
|
||||
import { logger } from "@/lib/logger";
|
||||
import { unstable_cache } from "next/cache";
|
||||
import { PrismaClient } from "@/generated/client";
|
||||
|
||||
const log = logger.child({ module: "prisma" });
|
||||
|
||||
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
||||
|
||||
const prisma = globalForPrisma.prisma || new PrismaClient();
|
||||
@ -7,3 +14,99 @@ const prisma = globalForPrisma.prisma || new PrismaClient();
|
||||
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
||||
|
||||
export default prisma;
|
||||
|
||||
const getProblems = async () => {
|
||||
const startTime = Date.now();
|
||||
log.debug("Fetching all problems from database");
|
||||
try {
|
||||
const problems = await prisma.problem.findMany();
|
||||
log.debug(
|
||||
{ count: problems.length, durationMs: Date.now() - startTime },
|
||||
"Fetched problems successfully"
|
||||
);
|
||||
return problems;
|
||||
} catch (error) {
|
||||
log.error(
|
||||
{ durationMs: Date.now() - startTime, error },
|
||||
"Failed to fetch problems"
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getCachedProblems = cache(
|
||||
unstable_cache(
|
||||
async () => {
|
||||
const startTime = Date.now();
|
||||
log.debug("Calling getProblemsCached (expect cache hit if warmed)");
|
||||
try {
|
||||
const result = await getProblems();
|
||||
log.info(
|
||||
{ durationMs: Date.now() - startTime },
|
||||
"getProblemsCached finished"
|
||||
);
|
||||
return result;
|
||||
} catch (error) {
|
||||
log.error(
|
||||
{ durationMs: Date.now() - startTime, error },
|
||||
"getProblemsCached failed"
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
["getProblems"],
|
||||
{
|
||||
tags: ["problems"],
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
const getProblem = async (id: string) => {
|
||||
const startTime = Date.now();
|
||||
log.debug({ id }, "Fetching single problem");
|
||||
try {
|
||||
const problem = await prisma.problem.findUnique({ where: { id } });
|
||||
if (problem) {
|
||||
log.debug({ id, durationMs: Date.now() - startTime }, "Problem found");
|
||||
} else {
|
||||
log.warn({ id, durationMs: Date.now() - startTime }, "Problem not found");
|
||||
}
|
||||
return problem;
|
||||
} catch (error) {
|
||||
log.error(
|
||||
{ id, durationMs: Date.now() - startTime, error },
|
||||
"Failed to fetch problem"
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
export const getCachedProblem = cache((id: string) =>
|
||||
unstable_cache(
|
||||
async () => {
|
||||
const startTime = Date.now();
|
||||
log.debug(
|
||||
{ id },
|
||||
"Calling getProblemCached (expect cache hit if warmed)"
|
||||
);
|
||||
try {
|
||||
const result = await getProblem(id);
|
||||
log.info(
|
||||
{ id, durationMs: Date.now() - startTime },
|
||||
"getProblemCached finished"
|
||||
);
|
||||
return result;
|
||||
} catch (error) {
|
||||
log.error(
|
||||
{ id, durationMs: Date.now() - startTime, error },
|
||||
"getProblemCached failed"
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
["getProblem", id],
|
||||
{
|
||||
tags: [`problem-${id}`],
|
||||
}
|
||||
)()
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user