Lets try ioredis
This commit is contained in:
parent
4341c2e7cc
commit
5e57e2b416
9 changed files with 90 additions and 103 deletions
|
@ -3,11 +3,8 @@ DATABASE_URL=""
|
|||
DATABASE_AUTH_TOKEN=""
|
||||
|
||||
# Redis
|
||||
UPSTASH_REDIS_REST_URL=""
|
||||
UPSTASH_REDIS_REST_TOKEN=""
|
||||
UPSTASH_REDIS_EXPIRY_SECONDS=""
|
||||
UPSTASH_RATELIMIT_REQUESTS=""
|
||||
UPSTASH_RATELIMIT_SECONDS=""
|
||||
REDIS_URL=""
|
||||
REDIS_EXPIRY_SECONDS=""
|
||||
|
||||
#Auth
|
||||
NEXT_PUBLIC_CLERK_SIGN_UP_URL="/sign-up"
|
||||
|
|
|
@ -48,10 +48,7 @@ const Navbar = ({ title }: NavbarProps) => {
|
|||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<span className="hidden md:inline-flex">
|
||||
{title}
|
||||
{env.NEXT_PUBLIC_APP_ENV === "development" && " >> Staging"}
|
||||
</span>
|
||||
<span className="hidden md:inline-flex">{title}</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { Redis } from "@upstash/redis";
|
||||
import { Redis } from "ioredis";
|
||||
import { env } from "env.mjs";
|
||||
|
||||
export const redis = Redis.fromEnv();
|
||||
export const redis = env.REDIS_URL ? new Redis(env.REDIS_URL) : null;
|
||||
|
||||
export const setCache = async <T>(key: string, value: T) => {
|
||||
console.log(env.REDIS_URL);
|
||||
try {
|
||||
await redis.set(`${env.APP_ENV}_${key}`, value, {
|
||||
ex: Number(env.UPSTASH_REDIS_EXPIRY_SECONDS),
|
||||
});
|
||||
await redis?.set(`${env.APP_ENV}_${key}`, JSON.stringify(value));
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
|
@ -16,8 +15,8 @@ export const setCache = async <T>(key: string, value: T) => {
|
|||
|
||||
export const fetchCache = async <T>(key: string) => {
|
||||
try {
|
||||
const result = await redis.get(`${env.APP_ENV}_${key}`);
|
||||
return result as T;
|
||||
const result = (await redis?.get(`${env.APP_ENV}_${key}`)) as string;
|
||||
return JSON.parse(result) as T;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
@ -25,7 +24,7 @@ export const fetchCache = async <T>(key: string) => {
|
|||
|
||||
export const invalidateCache = async (key: string) => {
|
||||
try {
|
||||
await redis.del(`${env.APP_ENV}_${key}`);
|
||||
await redis?.del(`${env.APP_ENV}_${key}`);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
|
|
|
@ -8,6 +8,7 @@ import { EventTypes } from "@/_utils/types";
|
|||
import { getAuth } from "@clerk/nextjs/server";
|
||||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { env } from "env.mjs";
|
||||
|
||||
export async function GET(
|
||||
request: Request,
|
||||
|
@ -61,7 +62,8 @@ export async function DELETE(
|
|||
const success = deletedRoom.length > 0;
|
||||
|
||||
if (success) {
|
||||
await invalidateCache(`kv_roomlist_${userId}`);
|
||||
if (env.APP_ENV === "production")
|
||||
await invalidateCache(`kv_roomlist_${userId}`);
|
||||
|
||||
await publishToMultipleChannels(
|
||||
[`${userId}`, `${params.roomId}`],
|
||||
|
|
|
@ -8,17 +8,21 @@ import { createId } from "@paralleldrive/cuid2";
|
|||
import { publishToChannel } from "@/_lib/ably";
|
||||
import { EventTypes } from "@/_utils/types";
|
||||
import { getAuth } from "@clerk/nextjs/server";
|
||||
import { env } from "env.mjs";
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const { userId } = getAuth(request as NextRequest);
|
||||
|
||||
const cachedResult = await fetchCache<
|
||||
{
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
roomName: string;
|
||||
}[]
|
||||
>(`kv_roomlist_${userId}`);
|
||||
const cachedResult =
|
||||
env.APP_ENV === "production"
|
||||
? await fetchCache<
|
||||
{
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
roomName: string;
|
||||
}[]
|
||||
>(`kv_roomlist_${userId}`)
|
||||
: null;
|
||||
|
||||
if (cachedResult) {
|
||||
return NextResponse.json(cachedResult, {
|
||||
|
@ -30,7 +34,8 @@ export async function GET(request: Request) {
|
|||
where: eq(rooms.userId, userId || ""),
|
||||
});
|
||||
|
||||
await setCache(`kv_roomlist_${userId}`, roomList);
|
||||
if (env.APP_ENV === "production")
|
||||
await setCache(`kv_roomlist_${userId}`, roomList);
|
||||
|
||||
return NextResponse.json(roomList, {
|
||||
status: 200,
|
||||
|
@ -60,7 +65,8 @@ export async function POST(request: Request) {
|
|||
const success = room.length > 0;
|
||||
|
||||
if (room) {
|
||||
await invalidateCache(`kv_roomlist_${userId}`);
|
||||
if (env.APP_ENV === "production")
|
||||
await invalidateCache(`kv_roomlist_${userId}`);
|
||||
|
||||
await publishToChannel(
|
||||
`${userId}`,
|
||||
|
|
7
env.mjs
7
env.mjs
|
@ -5,11 +5,8 @@ export const env = createEnv({
|
|||
server: {
|
||||
DATABASE_URL: z.string().url(),
|
||||
DATABASE_AUTH_TOKEN: z.string(),
|
||||
UPSTASH_REDIS_REST_URL: z.string().url(),
|
||||
UPSTASH_REDIS_REST_TOKEN: z.string(),
|
||||
UPSTASH_REDIS_EXPIRY_SECONDS: z.string(),
|
||||
UPSTASH_RATELIMIT_REQUESTS: z.string(),
|
||||
UPSTASH_RATELIMIT_SECONDS: z.string(),
|
||||
REDIS_URL: z.string().url().optional(),
|
||||
REDIS_EXPIRY_SECONDS: z.string().optional(),
|
||||
ABLY_API_KEY: z.string(),
|
||||
APP_ENV: z.string(),
|
||||
UNKEY_ROOT_KEY: z.string(),
|
||||
|
|
|
@ -1,21 +1,9 @@
|
|||
import { authMiddleware, redirectToSignIn } from "@clerk/nextjs";
|
||||
import { validateRequest } from "./app/_lib/unkey";
|
||||
import { NextResponse } from "next/server";
|
||||
import { Ratelimit } from "@upstash/ratelimit";
|
||||
import { Redis } from "@upstash/redis";
|
||||
import { env } from "./env.mjs";
|
||||
|
||||
const shitList = ["ama.ab.ca"];
|
||||
|
||||
const rateLimit = new Ratelimit({
|
||||
redis: Redis.fromEnv(),
|
||||
limiter: Ratelimit.slidingWindow(
|
||||
Number(env.UPSTASH_RATELIMIT_REQUESTS),
|
||||
`${Number(env.UPSTASH_RATELIMIT_SECONDS)}s`
|
||||
),
|
||||
analytics: true,
|
||||
});
|
||||
|
||||
export default authMiddleware({
|
||||
ignoredRoutes: ["/"],
|
||||
publicRoutes: [
|
||||
|
@ -25,14 +13,7 @@ export default authMiddleware({
|
|||
],
|
||||
afterAuth: async (auth, req) => {
|
||||
if (!auth.userId && auth.isPublicRoute) {
|
||||
const { success } = await rateLimit.limit(req.ip || "");
|
||||
if (success) {
|
||||
return NextResponse.next();
|
||||
}
|
||||
return new NextResponse("TOO MANY REQUESTS", {
|
||||
status: 429,
|
||||
statusText: "Too many requests!",
|
||||
});
|
||||
return NextResponse.next();
|
||||
}
|
||||
|
||||
if (auth.userId) {
|
||||
|
@ -54,15 +35,6 @@ export default authMiddleware({
|
|||
}
|
||||
|
||||
if (req.nextUrl.pathname.includes("/api/internal")) {
|
||||
const { success } = await rateLimit.limit(req.ip || "");
|
||||
|
||||
if (!success) {
|
||||
return new NextResponse("TOO MANY REQUESTS", {
|
||||
status: 429,
|
||||
statusText: "Too many requests!",
|
||||
});
|
||||
}
|
||||
|
||||
if (auth.userId) {
|
||||
return NextResponse.next();
|
||||
} else {
|
||||
|
@ -74,15 +46,6 @@ export default authMiddleware({
|
|||
}
|
||||
|
||||
if (req.nextUrl.pathname.includes("/api/external/private")) {
|
||||
const { success } = await rateLimit.limit(req.ip || "");
|
||||
|
||||
if (!success) {
|
||||
return new NextResponse("TOO MANY REQUESTS", {
|
||||
status: 429,
|
||||
statusText: "Too many requests!",
|
||||
});
|
||||
}
|
||||
|
||||
const isValid = await validateRequest(req);
|
||||
|
||||
if (isValid) {
|
||||
|
|
|
@ -21,14 +21,13 @@
|
|||
"@t3-oss/env-nextjs": "0.7.1",
|
||||
"@tanstack/react-query": "5.8.4",
|
||||
"@unkey/api": "0.12.0",
|
||||
"@upstash/ratelimit": "0.4.4",
|
||||
"@upstash/redis": "1.25.1",
|
||||
"@vercel/analytics": "1.1.1",
|
||||
"ably": "1.2.47",
|
||||
"autoprefixer": "10.4.16",
|
||||
"csv42": "5.0.0",
|
||||
"dotenv": "16.3.1",
|
||||
"drizzle-orm": "0.29.0",
|
||||
"ioredis": "^5.3.2",
|
||||
"next": "14.0.1",
|
||||
"nextjs-cors": "2.1.2",
|
||||
"postcss": "8.4.31",
|
||||
|
|
89
pnpm-lock.yaml
generated
89
pnpm-lock.yaml
generated
|
@ -26,12 +26,6 @@ dependencies:
|
|||
'@unkey/api':
|
||||
specifier: 0.12.0
|
||||
version: 0.12.0
|
||||
'@upstash/ratelimit':
|
||||
specifier: 0.4.4
|
||||
version: 0.4.4
|
||||
'@upstash/redis':
|
||||
specifier: 1.25.1
|
||||
version: 1.25.1
|
||||
'@vercel/analytics':
|
||||
specifier: 1.1.1
|
||||
version: 1.1.1
|
||||
|
@ -50,6 +44,9 @@ dependencies:
|
|||
drizzle-orm:
|
||||
specifier: 0.29.0
|
||||
version: 0.29.0(@libsql/client@0.4.0-pre.1)(better-sqlite3@9.1.1)
|
||||
ioredis:
|
||||
specifier: ^5.3.2
|
||||
version: 5.3.2
|
||||
next:
|
||||
specifier: 14.0.1
|
||||
version: 14.0.1(react-dom@18.2.0)(react@18.2.0)
|
||||
|
@ -800,6 +797,10 @@ packages:
|
|||
resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==}
|
||||
dev: true
|
||||
|
||||
/@ioredis/commands@1.2.0:
|
||||
resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==}
|
||||
dev: false
|
||||
|
||||
/@jridgewell/gen-mapping@0.3.3:
|
||||
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
@ -1548,25 +1549,6 @@ packages:
|
|||
resolution: {integrity: sha512-BT2I52rwTQ1j8S9aX9tKH3P3Efvtvgu8dD8pExYvKXG9uWPditNOwO6t8aeXLGCWdyzTqxmueBeR0uD0DN5U7A==}
|
||||
dev: false
|
||||
|
||||
/@upstash/core-analytics@0.0.6:
|
||||
resolution: {integrity: sha512-cpPSR0XJAJs4Ddz9nq3tINlPS5aLfWVCqhhtHnXt4p7qr5+/Znlt1Es736poB/9rnl1hAHrOsOvVj46NEXcVqA==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
dependencies:
|
||||
'@upstash/redis': 1.25.1
|
||||
dev: false
|
||||
|
||||
/@upstash/ratelimit@0.4.4:
|
||||
resolution: {integrity: sha512-y3q6cNDdcRQ2MRPRf5UNWBN36IwnZ4kAEkGoH3i6OqdWwz4qlBxNsw4/Rpqn9h93+Nx1cqg5IOq7O2e2zMJY1w==}
|
||||
dependencies:
|
||||
'@upstash/core-analytics': 0.0.6
|
||||
dev: false
|
||||
|
||||
/@upstash/redis@1.25.1:
|
||||
resolution: {integrity: sha512-ACj0GhJ4qrQyBshwFgPod6XufVEfKX2wcaihsEvSdLYnY+m+pa13kGt1RXm/yTHKf4TQi/Dy2A8z/y6WUEOmlg==}
|
||||
dependencies:
|
||||
crypto-js: 4.2.0
|
||||
dev: false
|
||||
|
||||
/@vercel/analytics@1.1.1:
|
||||
resolution: {integrity: sha512-+NqgNmSabg3IFfxYhrWCfB/H+RCUOCR5ExRudNG2+pcRehq628DJB5e1u1xqwpLtn4pAYii4D98w7kofORAGQA==}
|
||||
dependencies:
|
||||
|
@ -2031,6 +2013,11 @@ packages:
|
|||
mimic-response: 1.0.1
|
||||
dev: false
|
||||
|
||||
/cluster-key-slot@1.1.2:
|
||||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
|
@ -2097,10 +2084,6 @@ packages:
|
|||
which: 2.0.2
|
||||
dev: true
|
||||
|
||||
/crypto-js@4.2.0:
|
||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||
dev: false
|
||||
|
||||
/css-selector-tokenizer@0.8.0:
|
||||
resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==}
|
||||
dependencies:
|
||||
|
@ -2184,7 +2167,6 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
dev: true
|
||||
|
||||
/decompress-response@6.0.0:
|
||||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||
|
@ -2233,6 +2215,11 @@ packages:
|
|||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/denque@2.1.0:
|
||||
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
|
||||
engines: {node: '>=0.10'}
|
||||
dev: false
|
||||
|
||||
/dequal@2.0.3:
|
||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -3371,6 +3358,23 @@ packages:
|
|||
side-channel: 1.0.4
|
||||
dev: true
|
||||
|
||||
/ioredis@5.3.2:
|
||||
resolution: {integrity: sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
dependencies:
|
||||
'@ioredis/commands': 1.2.0
|
||||
cluster-key-slot: 1.1.2
|
||||
debug: 4.3.4
|
||||
denque: 2.1.0
|
||||
lodash.defaults: 4.2.0
|
||||
lodash.isarguments: 3.1.0
|
||||
redis-errors: 1.2.0
|
||||
redis-parser: 3.0.0
|
||||
standard-as-callback: 2.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/is-array-buffer@3.0.2:
|
||||
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
|
||||
dependencies:
|
||||
|
@ -3692,6 +3696,14 @@ packages:
|
|||
p-locate: 5.0.0
|
||||
dev: true
|
||||
|
||||
/lodash.defaults@4.2.0:
|
||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||
dev: false
|
||||
|
||||
/lodash.isarguments@3.1.0:
|
||||
resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==}
|
||||
dev: false
|
||||
|
||||
/lodash.merge@4.6.2:
|
||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||
dev: true
|
||||
|
@ -3844,7 +3856,6 @@ packages:
|
|||
|
||||
/ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
dev: true
|
||||
|
||||
/ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
@ -4363,6 +4374,18 @@ packages:
|
|||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/redis-errors@1.2.0:
|
||||
resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/redis-parser@3.0.0:
|
||||
resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
redis-errors: 1.2.0
|
||||
dev: false
|
||||
|
||||
/reflect.getprototypeof@1.0.4:
|
||||
resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -4664,6 +4687,10 @@ packages:
|
|||
get-source: 2.0.12
|
||||
dev: true
|
||||
|
||||
/standard-as-callback@2.1.0:
|
||||
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
|
||||
dev: false
|
||||
|
||||
/stoppable@1.1.0:
|
||||
resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==}
|
||||
engines: {node: '>=4', npm: '>=6'}
|
||||
|
|
Loading…
Add table
Reference in a new issue