Redis overhaul

This commit is contained in:
Atridad Lahiji 2023-07-03 15:37:14 -06:00 committed by atridadl
parent f5cdf2992c
commit 236c34e85d
No known key found for this signature in database
7 changed files with 75 additions and 61 deletions

View file

@ -4,7 +4,7 @@ import { publishToChannel } from "~/server/ably";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import { env } from "~/env.mjs";
import { redis } from "~/server/redis";
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
export const roomRouter = createTRPCRouter({
// Create
@ -26,8 +26,8 @@ export const roomRouter = createTRPCRouter({
},
});
if (room) {
await redis.del(`${env.APP_ENV}_kv_roomcount_admin`);
await redis.del(`${env.APP_ENV}_kv_roomlist_${ctx.session.user.id}`);
await invalidateCache(`kv_roomcount_admin`);
await invalidateCache(`kv_roomlist_${ctx.session.user.id}`);
await publishToChannel(
`${ctx.session.user.id}`,
@ -66,13 +66,13 @@ export const roomRouter = createTRPCRouter({
// Get All
getAll: protectedProcedure.query(async ({ ctx }) => {
const cachedResult = await redis.get<
const cachedResult = await fetchCache<
{
id: string;
createdAt: Date;
roomName: string;
}[]
>(`${env.APP_ENV}_kv_roomlist_${ctx.session.user.id}`);
>(`kv_roomlist_${ctx.session.user.id}`);
if (cachedResult) {
return cachedResult;
@ -88,29 +88,21 @@ export const roomRouter = createTRPCRouter({
},
});
await redis.set(
`${env.APP_ENV}_kv_roomlist_${ctx.session.user.id}`,
roomList,
{ ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS) }
);
await setCache(`kv_roomlist_${ctx.session.user.id}`, roomList);
return roomList;
}
}),
countAll: protectedProcedure.query(async ({ ctx }) => {
const cachedResult = await redis.get<number>(
`${env.APP_ENV}_kv_roomcount_admin`
);
const cachedResult = await fetchCache<number>(`kv_roomcount_admin`);
if (cachedResult) {
return cachedResult;
} else {
const roomsCount = await ctx.prisma.room.count();
await redis.set(`${env.APP_ENV}_kv_roomcount_admin`, roomsCount, {
ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS),
});
await setCache(`kv_roomcount_admin`, roomsCount);
return roomsCount;
}
@ -176,7 +168,7 @@ export const roomRouter = createTRPCRouter({
},
});
await redis.del(`${env.APP_ENV}_kv_votes_${input.roomId}`);
await invalidateCache(`kv_votes_${input.roomId}`);
}
const newRoom = await ctx.prisma.room.update({
@ -228,9 +220,9 @@ export const roomRouter = createTRPCRouter({
});
if (deletedRoom) {
await redis.del(`${env.APP_ENV}_kv_roomcount_admin`);
await redis.del(`${env.APP_ENV}_kv_votecount_admin`);
await redis.del(`${env.APP_ENV}_kv_roomlist_${ctx.session.user.id}`);
await invalidateCache(`kv_roomcount_admin`);
await invalidateCache(`kv_votecount_admin`);
await invalidateCache(`kv_roomlist_${ctx.session.user.id}`);
await publishToChannel(
`${ctx.session.user.id}`,

View file

@ -1,7 +1,7 @@
import { z } from "zod";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import { env } from "~/env.mjs";
import { redis } from "~/server/redis";
import { invalidateCache } from "~/server/redis";
export const sessionRouter = createTRPCRouter({
deleteAllByUserId: protectedProcedure
@ -18,7 +18,7 @@ export const sessionRouter = createTRPCRouter({
});
if (!!sessions) {
await redis.del(`${env.APP_ENV}_kv_userlist_admin`);
await invalidateCache(`kv_userlist_admin`);
}
return !!sessions;
@ -27,7 +27,7 @@ export const sessionRouter = createTRPCRouter({
const sessions = await ctx.prisma.session.deleteMany();
if (!!sessions) {
await redis.del(`${env.APP_ENV}_kv_userlist_admin`);
await invalidateCache(`kv_userlist_admin`);
}
return !!sessions;

View file

@ -6,24 +6,20 @@ import type { Role } from "~/utils/types";
import { Resend } from "resend";
import { Goodbye } from "~/components/templates/Goodbye";
import { redis } from "~/server/redis";
import { setCache, fetchCache, invalidateCache } from "~/server/redis";
const resend = new Resend(process.env.RESEND_API_KEY);
export const userRouter = createTRPCRouter({
countAll: protectedProcedure.query(async ({ ctx }) => {
const cachedResult = await redis.get<number>(
`${env.APP_ENV}_kv_usercount_admin`
);
const cachedResult = await fetchCache<number>(`kv_usercount_admin`);
if (cachedResult) {
return cachedResult;
} else {
const usersCount = await ctx.prisma.user.count();
await redis.set(`${env.APP_ENV}_kv_usercount_admin`, usersCount, {
ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS),
});
await setCache(`kv_usercount_admin`, usersCount);
return usersCount;
}
@ -48,7 +44,7 @@ export const userRouter = createTRPCRouter({
});
}),
getAll: protectedProcedure.query(async ({ ctx }) => {
const cachedResult = await redis.get<
const cachedResult = await fetchCache<
{
accounts: {
provider: string;
@ -62,7 +58,7 @@ export const userRouter = createTRPCRouter({
name: string | null;
email: string | null;
}[]
>(`${env.APP_ENV}_kv_userlist_admin`);
>(`kv_userlist_admin`);
if (cachedResult) {
return cachedResult.map((user) => {
@ -92,9 +88,7 @@ export const userRouter = createTRPCRouter({
},
});
await redis.set(`${env.APP_ENV}_kv_userlist_admin`, users, {
ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS),
});
await setCache(`${env.APP_ENV}_kv_userlist_admin`, users);
return users;
}
@ -132,8 +126,8 @@ export const userRouter = createTRPCRouter({
react: Goodbye({ name: user.name }),
});
await redis.del(`${env.APP_ENV}_kv_usercount_admin`);
await redis.del(`${env.APP_ENV}_kv_userlist_admin`);
await invalidateCache(`kv_usercount_admin`);
await invalidateCache(`kv_userlist_admin`);
}
return !!user;
@ -173,7 +167,7 @@ export const userRouter = createTRPCRouter({
},
});
await redis.del(`${env.APP_ENV}_kv_userlist_admin`);
await invalidateCache(`kv_userlist_admin`);
return !!user;
}),

View file

@ -4,22 +4,18 @@ import { publishToChannel } from "~/server/ably";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import { env } from "~/env.mjs";
import type { Room } from "@prisma/client";
import { redis } from "~/server/redis";
import { fetchCache, invalidateCache, setCache } from "~/server/redis";
export const voteRouter = createTRPCRouter({
countAll: protectedProcedure.query(async ({ ctx }) => {
const cachedResult = await redis.get<number>(
`${env.APP_ENV}_kv_votecount_admin`
);
const cachedResult = await fetchCache<number>(`kv_votecount_admin`);
if (cachedResult) {
return cachedResult;
} else {
const votesCount = await ctx.prisma.vote.count();
await redis.set(`${env.APP_ENV}_kv_votecount_admin`, votesCount, {
ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS),
});
await setCache(`kv_votecount_admin`, votesCount);
return votesCount;
}
@ -27,7 +23,7 @@ export const voteRouter = createTRPCRouter({
getAllByRoomId: protectedProcedure
.input(z.object({ roomId: z.string() }))
.query(async ({ ctx, input }) => {
const cachedResult = await redis.get<
const cachedResult = await fetchCache<
{
value: string;
room: Room;
@ -39,7 +35,7 @@ export const voteRouter = createTRPCRouter({
};
roomId: string;
}[]
>(`${env.APP_ENV}_kv_votes_${input.roomId}`);
>(`kv_votes_${input.roomId}`);
if (cachedResult) {
return cachedResult;
@ -63,11 +59,7 @@ export const voteRouter = createTRPCRouter({
},
});
await redis.set(
`${env.APP_ENV}_kv_votes_${input.roomId}`,
votesByRoomId,
{ ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS) }
);
await setCache(`kv_votes_${input.roomId}`, votesByRoomId);
return votesByRoomId;
}
@ -106,8 +98,8 @@ export const voteRouter = createTRPCRouter({
});
if (vote) {
await redis.del(`${env.APP_ENV}_kv_votecount_admin`);
await redis.del(`${env.APP_ENV}_kv_votes_${input.roomId}`);
await invalidateCache(`kv_votecount_admin`);
await invalidateCache(`kv_votes_${input.roomId}`);
await publishToChannel(`${vote.roomId}`, "VOTE_UPDATE", "UPDATE");
}

View file

@ -19,9 +19,10 @@ import { type Session } from "next-auth";
import { getServerAuthSession } from "~/server/auth";
import { prisma } from "~/server/db";
import { Redis } from "@upstash/redis";
const rateLimit = new Ratelimit({
redis,
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(
Number(env.UPSTASH_RATELIMIT_REQUESTS),
`${Number(env.UPSTASH_RATELIMIT_SECONDS)}s`
@ -75,7 +76,6 @@ export const createTRPCContext = async (opts: CreateNextContextOptions) => {
import { initTRPC, TRPCError } from "@trpc/server";
import superjson from "superjson";
import { Ratelimit } from "@upstash/ratelimit";
import { redis } from "../redis";
import { env } from "~/env.mjs";
const t = initTRPC.context<typeof createTRPCContext>().create({

View file

@ -12,7 +12,7 @@ import { prisma } from "~/server/db";
import type { Role } from "~/utils/types";
import { Resend } from "resend";
import { Welcome } from "../components/templates/Welcome";
import { redis } from "./redis";
import { invalidateCache } from "./redis";
const resend = new Resend(process.env.RESEND_API_KEY);
@ -61,15 +61,15 @@ export const authOptions: NextAuthOptions = {
react: Welcome({ name: user.name }),
});
await redis.del(`${env.APP_ENV}_kv_userlist_admin`);
await redis.del(`${env.APP_ENV}_kv_usercount_admin`);
await invalidateCache(`kv_userlist_admin`);
await invalidateCache(`kv_usercount_admin`);
}
},
async signIn({}) {
await redis.del(`${env.APP_ENV}_kv_userlist_admin`);
await invalidateCache(`kv_userlist_admin`);
},
async signOut() {
await redis.del(`${env.APP_ENV}_kv_userlist_admin`);
await invalidateCache(`kv_userlist_admin`);
},
},
// @ts-ignore This adapter should work...

View file

@ -1,6 +1,42 @@
import { Redis } from "@upstash/redis";
import https from "https";
import { env } from "~/env.mjs";
export const redis = Redis.fromEnv({
agent: new https.Agent({ keepAlive: true }),
});
export const setCache = async <T>(key: string, value: T) => {
try {
await redis.set(`${env.APP_ENV}_${key}`, value, {
ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS),
});
return true;
} catch {
return false;
}
};
export const fetchCache = async <T>(key: string) => {
try {
const result = await redis.get(`${env.APP_ENV}_${key}`);
if (result) {
console.log("CACHE HIT");
} else {
console.log("CACHE MISS");
}
return result as T;
} catch {
console.log("CACHE ERROR");
return null;
}
};
export const invalidateCache = async (key: string) => {
try {
await redis.del(`${env.APP_ENV}_${key}`);
return true;
} catch {
return false;
}
};