Skip to content

Commit

Permalink
feat: add cache more data (#5052)
Browse files Browse the repository at this point in the history
  • Loading branch information
bigint committed Jul 10, 2024
2 parents 1a7841c + c377036 commit 87c8615
Show file tree
Hide file tree
Showing 24 changed files with 110 additions and 17 deletions.
2 changes: 1 addition & 1 deletion apps/api/src/helpers/middlewares/rateLimiter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';

import catchedError from '../catchedError';
import redisClient from '../redis';
import redisClient from '../redisClient';

const hashedIp = (req: Request): string => sha256(getIp(req)).slice(0, 25);

Expand Down
File renamed without changes.
12 changes: 12 additions & 0 deletions apps/api/src/routes/internal/features/assign.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import type { Request, Response } from 'express';

import { VERIFIED_FEATURE_ID } from '@hey/data/constants';
import logger from '@hey/helpers/logger';
import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import validateIsStaff from 'src/helpers/middlewares/validateIsStaff';
import validateLensAccount from 'src/helpers/middlewares/validateLensAccount';
import redisClient from 'src/helpers/redisClient';
import { invalidBody, noBody } from 'src/helpers/responses';
import { boolean, object, string } from 'zod';

const clearCache = async (profileId: string, featureId: string) => {
await redisClient.del(`preference:${profileId}`);
await redisClient.del(`profile:${profileId}`);
if (featureId === VERIFIED_FEATURE_ID) {
await redisClient.del('verified');
}
};

type ExtensionRequest = {
enabled: boolean;
id: string;
Expand Down Expand Up @@ -49,6 +59,7 @@ export const post = [
[id, profile_id]
);

await clearCache(profile_id, id);
logger.info(`Enabled features for ${profile_id}`);

return res.status(200).json({ enabled, success: true });
Expand All @@ -62,6 +73,7 @@ export const post = [
[profile_id, id]
);

await clearCache(profile_id, id);
logger.info(`Disabled features for ${profile_id}`);

return res.status(200).json({ enabled, success: true });
Expand Down
14 changes: 13 additions & 1 deletion apps/api/src/routes/internal/preferences/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import validateIsStaff from 'src/helpers/middlewares/validateIsStaff';
import validateLensAccount from 'src/helpers/middlewares/validateLensAccount';
import redisClient from 'src/helpers/redisClient';
import { noBody } from 'src/helpers/responses';

export const get = [
Expand All @@ -18,6 +19,16 @@ export const get = [
return noBody(res);
}

const cacheKey = `preference:${id}`;
const cachedPreference = await redisClient.get(cacheKey);

if (cachedPreference) {
logger.info(`(cached) Internal profile preferences fetched for ${id}`);
return res
.status(200)
.json({ result: JSON.parse(cachedPreference), success: true });
}

try {
const [preference, features, email, membershipNft] = await heyPg.multi(
`
Expand Down Expand Up @@ -50,7 +61,8 @@ export const get = [
)
};

logger.info(`Profile preferences fetched for ${id}`);
await redisClient.set(cacheKey, JSON.stringify(response));
logger.info(`Internal profile preferences fetched for ${id}`);

return res.status(200).json({ result: response, success: true });
} catch (error) {
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/routes/internal/tokens/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import validateIsStaff from 'src/helpers/middlewares/validateIsStaff';
import validateLensAccount from 'src/helpers/middlewares/validateLensAccount';
import redisClient from 'src/helpers/redisClient';
import { invalidBody, noBody } from 'src/helpers/responses';
import { number, object, string } from 'zod';

Expand Down Expand Up @@ -55,6 +56,7 @@ export const post = [
[contractAddress, decimals, name, symbol]
);

await redisClient.del(`allowedTokens`);
logger.info(`Created a token ${token[0]?.id}`);

return res.status(200).json({ success: true, token: token[0] });
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/routes/internal/tokens/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import validateIsStaff from 'src/helpers/middlewares/validateIsStaff';
import validateLensAccount from 'src/helpers/middlewares/validateLensAccount';
import redisClient from 'src/helpers/redisClient';
import { invalidBody, noBody } from 'src/helpers/responses';
import { object, string } from 'zod';

Expand Down Expand Up @@ -36,6 +37,7 @@ export const post = [

try {
await heyPg.query(`DELETE FROM "AllowedToken" WHERE id = $1`, [id]);
await redisClient.del(`allowedTokens`);
logger.info(`Deleted a token ${id}`);

return res.status(200).json({ success: true });
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/lens/internal/stats/heyRevenue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const get = [
signups_count: Number(row.signups_count)
}));

logger.info('Lens: Fetched signup and membership NFT stats');
logger.info('[Lens] Fetched signup and membership NFT stats');

return res.status(200).json({ result: formattedResult, success: true });
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/lens/internal/stats/publication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const get = [
GROUP BY app;
`);

logger.info('Lens: Fetched publication stats');
logger.info('[Lens] Fetched publication stats');

return res.status(200).json({ result: result[0], success: true });
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/lens/internal/stats/revenue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const get = [
ORDER BY month, revenue DESC;
`);

logger.info('Lens: Fetched app revenue');
logger.info('[Lens] Fetched app revenue');

return res.status(200).json({ result, success: true });
} catch (error) {
Expand Down
17 changes: 15 additions & 2 deletions apps/api/src/routes/lens/rate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@ import logger from '@hey/helpers/logger';
import lensPg from 'src/db/lensPg';
import catchedError from 'src/helpers/catchedError';
import { CACHE_AGE_30_MINS } from 'src/helpers/constants';
import redisClient from 'src/helpers/redisClient';

// TODO: add tests
export const get: Handler = async (req, res) => {
export const get: Handler = async (_, res) => {
try {
const cacheKey = 'rates';
const cachedRates = await redisClient.get(cacheKey);

if (cachedRates) {
logger.info('(cached) [Lens] Fetched USD conversion rates');
return res
.status(200)
.setHeader('Cache-Control', CACHE_AGE_30_MINS)
.json({ result: JSON.parse(cachedRates), success: true });
}

const response = await lensPg.query(`
SELECT ec.name AS name,
ec.symbol AS symbol,
Expand All @@ -27,7 +39,8 @@ export const get: Handler = async (req, res) => {
symbol: row.symbol
}));

logger.info('Lens: Fetched USD conversion rates');
await redisClient.set(cacheKey, JSON.stringify(result));
logger.info('[Lens] Fetched USD conversion rates');

return res
.status(200)
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/lens/stats/profile/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const get: Handler = async (req, res) => {
total_notifications: Number(notificationStats[0]?.total_notifications)
};

logger.info(`Lens: Fetched global profile stats for ${id}`);
logger.info(`[Lens] Fetched global profile stats for ${id}`);

return res
.status(200)
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import catchedError from 'src/helpers/catchedError';
import { SCORE_WORKER_URL } from 'src/helpers/constants';
import createClickhouseClient from 'src/helpers/createClickhouseClient';
import { rateLimiter } from 'src/helpers/middlewares/rateLimiter';
import redisClient from 'src/helpers/redis';
import redisClient from 'src/helpers/redisClient';

const measureQueryTime = async (
queryFunction: () => Promise<any>
Expand Down
13 changes: 13 additions & 0 deletions apps/api/src/routes/misc/verified.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,21 @@ import logger from '@hey/helpers/logger';
import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import { CACHE_AGE_30_MINS, VERIFIED_FEATURE_ID } from 'src/helpers/constants';
import redisClient from 'src/helpers/redisClient';

export const get: Handler = async (_, res) => {
try {
const cacheKey = 'verified';
const verifiedIds = await redisClient.get(cacheKey);

if (verifiedIds) {
logger.info('(cached) Verified profiles fetched');
return res
.status(200)
.setHeader('Cache-Control', CACHE_AGE_30_MINS)
.json({ result: JSON.parse(verifiedIds), success: true });
}

const data = await heyPg.query(
`
SELECT "profileId"
Expand All @@ -18,6 +30,7 @@ export const get: Handler = async (_, res) => {
);

const ids = data.map(({ profileId }) => profileId);
await redisClient.set(cacheKey, JSON.stringify(ids));
logger.info('Verified profiles fetched');

return res
Expand Down
12 changes: 12 additions & 0 deletions apps/api/src/routes/preferences/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import parseJwt from '@hey/helpers/parseJwt';
import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import validateLensAccount from 'src/helpers/middlewares/validateLensAccount';
import redisClient from 'src/helpers/redisClient';
import { noBody } from 'src/helpers/responses';

export const get = [
Expand All @@ -20,6 +21,16 @@ export const get = [
return noBody(res);
}

const cacheKey = `preference:${id}`;
const cachedPreference = await redisClient.get(cacheKey);

if (cachedPreference) {
logger.info(`(cached) Profile preferences fetched for ${id}`);
return res
.status(200)
.json({ result: JSON.parse(cachedPreference), success: true });
}

const [preference, features, email, membershipNft] = await heyPg.multi(
`
SELECT * FROM "Preference" WHERE id = $1;
Expand Down Expand Up @@ -51,6 +62,7 @@ export const get = [
)
};

await redisClient.set(cacheKey, JSON.stringify(response));
logger.info(`Profile preferences fetched for ${id}`);

return res.status(200).json({ result: response, success: true });
Expand Down
2 changes: 2 additions & 0 deletions apps/api/src/routes/preferences/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import parseJwt from '@hey/helpers/parseJwt';
import catchedError from 'src/helpers/catchedError';
import validateLensAccount from 'src/helpers/middlewares/validateLensAccount';
import prisma from 'src/helpers/prisma';
import redisClient from 'src/helpers/redisClient';
import { invalidBody, noBody } from 'src/helpers/responses';
import { boolean, number, object, string } from 'zod';

Expand Down Expand Up @@ -47,6 +48,7 @@ export const post = [
where: { id: payload.id }
});

await redisClient.del(`preference:${payload.id}`);
logger.info(`Updated preferences for ${payload.id}`);

return res.status(200).json({ result: data, success: true });
Expand Down
12 changes: 12 additions & 0 deletions apps/api/src/routes/profile/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import logger from '@hey/helpers/logger';
import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import { SUSPENDED_FEATURE_ID } from 'src/helpers/constants';
import redisClient from 'src/helpers/redisClient';
import { noBody } from 'src/helpers/responses';

export const get: Handler = async (req, res) => {
Expand All @@ -15,6 +16,16 @@ export const get: Handler = async (req, res) => {
}

try {
const cacheKey = `profile:${id}`;
const cachedProfile = await redisClient.get(cacheKey);

if (cachedProfile) {
logger.info(`(cached) Profile details fetched for ${id}`);
return res
.status(200)
.json({ result: JSON.parse(cachedProfile), success: true });
}

const [profileFeature, pinnedPublication] = await heyPg.multi(
`
SELECT * FROM "ProfileFeature"
Expand All @@ -30,6 +41,7 @@ export const get: Handler = async (req, res) => {
pinnedPublication: pinnedPublication[0]?.publicationId || null
};

await redisClient.set(cacheKey, JSON.stringify(response));
logger.info(`Profile details fetched for ${id}`);

return res.status(200).json({ result: response, success: true });
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/score/allocations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const get: Handler = async (req, res) => {
}));

logger.info(
`Lens: Fetched ${adjustedProfileScore.length} allocations for ${id}`
`[Lens] Fetched ${adjustedProfileScore.length} allocations for ${id}`
);

return res.status(200).json({ result, success: true });
Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/routes/score/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const get: Handler = async (req, res) => {
new Date() < cachedProfileData.expiresAt
) {
logger.info(
`Lens: Fetched profile score from cache for ${id} - ${cachedProfileData.score}`
`[Lens] Fetched profile score from cache for ${id} - ${cachedProfileData.score}`
);
return res
.status(200)
Expand Down Expand Up @@ -117,7 +117,7 @@ export const get: Handler = async (req, res) => {
);

logger.info(
`Lens: Fetched profile score for ${id} - ${newCachedProfile[0]?.score} - Expires at: ${newCachedProfile[0]?.expiresAt}`
`[Lens] Fetched profile score for ${id} - ${newCachedProfile[0]?.score} - Expires at: ${newCachedProfile[0]?.expiresAt}`
);

return res
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/sitemap/others.xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const get: Handler = (req, res) => {
const entries = sitemaps.map((sitemap) => ({ loc: sitemap }));
const xml = buildUrlsetXml(entries);

logger.info(`Lens: Fetched other sitemaps from user-agent: ${user_agent}`);
logger.info(`[Lens] Fetched other sitemaps from user-agent: ${user_agent}`);

return res.status(200).setHeader('Content-Type', 'text/xml').send(xml);
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/sitemap/profiles.xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const get: Handler = async (req, res) => {
const xml = buildSitemapXml(entries);

logger.info(
`Lens: Fetched all profiles sitemap index having ${totalBatches} batches from user-agent: ${user_agent}`
`[Lens] Fetched all profiles sitemap index having ${totalBatches} batches from user-agent: ${user_agent}`
);

return res.status(200).setHeader('Content-Type', 'text/xml').send(xml);
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/sitemap/profiles/[id].xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const get: Handler = async (req, res) => {
const xml = buildUrlsetXml(entries);

logger.info(
`Lens: Fetched profiles sitemap for batch ${batch} having ${response.length} entries from user-agent: ${user_agent}`
`[Lens] Fetched profiles sitemap for batch ${batch} having ${response.length} entries from user-agent: ${user_agent}`
);

return res.status(200).setHeader('Content-Type', 'text/xml').send(xml);
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/routes/sitemap/sitemap.xml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const get: Handler = (req, res) => {
const xml = buildSitemapXml(entries);

logger.info(
`Lens: Fetched all sitemaps index from user-agent: ${user_agent}`
`[Lens] Fetched all sitemaps index from user-agent: ${user_agent}`
);

return res.status(200).setHeader('Content-Type', 'text/xml').send(xml);
Expand Down
13 changes: 13 additions & 0 deletions apps/api/src/routes/tokens/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,28 @@ import logger from '@hey/helpers/logger';
import heyPg from 'src/db/heyPg';
import catchedError from 'src/helpers/catchedError';
import { CACHE_AGE_1_DAY } from 'src/helpers/constants';
import redisClient from 'src/helpers/redisClient';

export const get: Handler = async (_, res) => {
try {
const cacheKey = 'allowedTokens';
const cachedTokens = await redisClient.get(cacheKey);

if (cachedTokens) {
logger.info('(cached) All tokens fetched');
return res
.status(200)
.setHeader('Cache-Control', CACHE_AGE_1_DAY)
.json({ result: JSON.parse(cachedTokens), success: true });
}

const data = await heyPg.query(`
SELECT *
FROM "AllowedToken"
ORDER BY priority DESC;
`);

await redisClient.set(cacheKey, JSON.stringify(data));
logger.info('All tokens fetched');

return res
Expand Down
Loading

1 comment on commit 87c8615

@vercel
Copy link

@vercel vercel bot commented on 87c8615 Jul 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

web – ./apps/web

web-heyxyz.vercel.app
heyxyz.vercel.app
web-git-main-heyxyz.vercel.app
hey.xyz

Please sign in to comment.