Add SKIP_REDIS environment variable and handle KeyDB client initialization in various services
This commit is contained in:
parent
edd57928c7
commit
ef58dc618c
7 changed files with 43 additions and 1 deletions
1
apps/infoalloggi/.github/workflows/ci.yml
vendored
1
apps/infoalloggi/.github/workflows/ci.yml
vendored
|
|
@ -26,6 +26,7 @@ env:
|
||||||
TILES_URL: "keydb://string"
|
TILES_URL: "keydb://string"
|
||||||
KEYDB_URL: "keydb://string"
|
KEYDB_URL: "keydb://string"
|
||||||
JWT_SECRET: "335922ae"
|
JWT_SECRET: "335922ae"
|
||||||
|
SKIP_REDIS: "false"
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ ENV KEYDB_URL=$KEYDB_URL
|
||||||
ARG TILES_URL
|
ARG TILES_URL
|
||||||
ENV TILES_URL=$TILES_URL
|
ENV TILES_URL=$TILES_URL
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV SKIP_REDIS=1
|
||||||
|
|
||||||
RUN SKIP_ENV_VALIDATION=1 npm run build
|
RUN SKIP_ENV_VALIDATION=1 npm run build
|
||||||
|
|
||||||
|
|
@ -117,6 +118,7 @@ ENV KEYDB_URL=$KEYDB_URL
|
||||||
ARG TILES_URL
|
ARG TILES_URL
|
||||||
ENV TILES_URL=$TILES_URL
|
ENV TILES_URL=$TILES_URL
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV SKIP_REDIS=0
|
||||||
|
|
||||||
RUN addgroup -g 1001 -S nodejs
|
RUN addgroup -g 1001 -S nodejs
|
||||||
RUN adduser -S nextjs -u 1001
|
RUN adduser -S nextjs -u 1001
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ const server = z.object({
|
||||||
TILES_URL: z.string(),
|
TILES_URL: z.string(),
|
||||||
KEYDB_URL: z.string(),
|
KEYDB_URL: z.string(),
|
||||||
JWT_SECRET: z.string(),
|
JWT_SECRET: z.string(),
|
||||||
|
SKIP_REDIS: z.coerce.boolean(),
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -70,6 +71,7 @@ const processEnv = {
|
||||||
TILES_URL: process.env.TILES_URL,
|
TILES_URL: process.env.TILES_URL,
|
||||||
KEYDB_URL: process.env.KEYDB_URL,
|
KEYDB_URL: process.env.KEYDB_URL,
|
||||||
JWT_SECRET: process.env.JWT_SECRET,
|
JWT_SECRET: process.env.JWT_SECRET,
|
||||||
|
SKIP_REDIS: process.env.SKIP_REDIS,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Don't touch the part below
|
// Don't touch the part below
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,13 @@ export const chatSSERouter = createTRPCRouter({
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const chatKey = `chat:${input.chatId}:onlineUsers`;
|
const chatKey = `chat:${input.chatId}:onlineUsers`;
|
||||||
const keydb = getKeydbClient();
|
const keydb = getKeydbClient();
|
||||||
|
|
||||||
|
if (!keydb) {
|
||||||
|
console.warn(
|
||||||
|
"KeyDB client is not initialized. Skipping online status.",
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
// Add the user to the Redis set
|
// Add the user to the Redis set
|
||||||
await keydb.sadd(
|
await keydb.sadd(
|
||||||
chatKey,
|
chatKey,
|
||||||
|
|
@ -114,6 +121,12 @@ export const chatSSERouter = createTRPCRouter({
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
const chatKey = `chat:${input.chatId}:onlineUsers`;
|
const chatKey = `chat:${input.chatId}:onlineUsers`;
|
||||||
const keydb = getKeydbClient();
|
const keydb = getKeydbClient();
|
||||||
|
if (!keydb) {
|
||||||
|
console.warn(
|
||||||
|
"KeyDB client is not initialized. Skipping online status.",
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
// Remove the user from the Redis set
|
// Remove the user from the Redis set
|
||||||
await keydb.srem(
|
await keydb.srem(
|
||||||
chatKey,
|
chatKey,
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,10 @@ export const addTyping = async ({
|
||||||
userId,
|
userId,
|
||||||
username,
|
username,
|
||||||
});
|
});
|
||||||
|
if (!keydb) {
|
||||||
|
console.warn("KeyDB client is not initialized. Skipping typing status.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Add the user to the Redis set with a TTL
|
// Add the user to the Redis set with a TTL
|
||||||
await keydb.zadd(typingKey, new Date().getTime(), typingData);
|
await keydb.zadd(typingKey, new Date().getTime(), typingData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -233,6 +236,10 @@ export const removeTyping = async ({
|
||||||
try {
|
try {
|
||||||
const keydb = getKeydbClient();
|
const keydb = getKeydbClient();
|
||||||
const typingKey = `${TYPING_KEY_PREFIX}${chatId}`;
|
const typingKey = `${TYPING_KEY_PREFIX}${chatId}`;
|
||||||
|
if (!keydb) {
|
||||||
|
console.warn("KeyDB client is not initialized. Skipping typing removal.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await keydb.zrem(typingKey, JSON.stringify({ userId, username }));
|
await keydb.zrem(typingKey, JSON.stringify({ userId, username }));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -250,6 +257,12 @@ export const removeStaleTyping = async (chatId: ChatsChatid) => {
|
||||||
const typingKey = `${TYPING_KEY_PREFIX}${chatId}`;
|
const typingKey = `${TYPING_KEY_PREFIX}${chatId}`;
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const cutoff = subSeconds(now, TYPING_TTL_SECONDS);
|
const cutoff = subSeconds(now, TYPING_TTL_SECONDS);
|
||||||
|
if (!keydb) {
|
||||||
|
console.warn(
|
||||||
|
"KeyDB client is not initialized. Skipping stale typing removal.",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await keydb.zremrangebyscore(typingKey, 0, cutoff.getTime());
|
await keydb.zremrangebyscore(typingKey, 0, cutoff.getTime());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -268,6 +281,10 @@ export const getCurrentlyTyping = async (
|
||||||
try {
|
try {
|
||||||
const keydb = getKeydbClient();
|
const keydb = getKeydbClient();
|
||||||
const typingKey = `${TYPING_KEY_PREFIX}${chatId}`;
|
const typingKey = `${TYPING_KEY_PREFIX}${chatId}`;
|
||||||
|
if (!keydb) {
|
||||||
|
console.warn("KeyDB client is not initialized. Skipping typing status.");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch all members of the Redis set
|
// Fetch all members of the Redis set
|
||||||
const allTypers = await keydb.zrange(typingKey, 0, -1);
|
const allTypers = await keydb.zrange(typingKey, 0, -1);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,10 @@ export class RateLimiterHandler {
|
||||||
* @param key The key to limit, "event_identifier" is recommended
|
* @param key The key to limit, "event_identifier" is recommended
|
||||||
*/
|
*/
|
||||||
async limit(key: string): Promise<{ success: boolean }> {
|
async limit(key: string): Promise<{ success: boolean }> {
|
||||||
|
if (!keydb) {
|
||||||
|
console.warn("KeyDB client is not initialized. Skipping rate limiting.");
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
const redisKey = `ratelimiter:${key}`;
|
const redisKey = `ratelimiter:${key}`;
|
||||||
const { windowSize, maxRequests, analytics } = this.config;
|
const { windowSize, maxRequests, analytics } = this.config;
|
||||||
// Increment the count atomically
|
// Increment the count atomically
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ import { env } from "~/env.mjs";
|
||||||
let keydb: Redis | null = null;
|
let keydb: Redis | null = null;
|
||||||
|
|
||||||
export function getKeydbClient() {
|
export function getKeydbClient() {
|
||||||
|
if (env.SKIP_REDIS) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (!keydb) {
|
if (!keydb) {
|
||||||
keydb = new Redis(`keydb://${env.KEYDB_URL}`);
|
keydb = new Redis(`keydb://${env.KEYDB_URL}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue