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,9 +1,112 @@
|
|||||||
|
import "server-only";
|
||||||
|
|
||||||
|
import { cache } from "react";
|
||||||
|
import { logger } from "@/lib/logger";
|
||||||
|
import { unstable_cache } from "next/cache";
|
||||||
import { PrismaClient } from "@/generated/client";
|
import { PrismaClient } from "@/generated/client";
|
||||||
|
|
||||||
|
const log = logger.child({ module: "prisma" });
|
||||||
|
|
||||||
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
||||||
|
|
||||||
const prisma = globalForPrisma.prisma || new PrismaClient();
|
const prisma = globalForPrisma.prisma || new PrismaClient();
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
||||||
|
|
||||||
export default 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