Refactored caching logic.

This commit is contained in:
Mike Cao 2024-04-26 00:31:38 -07:00
parent 216304a191
commit 0fc8828f8b
7 changed files with 33 additions and 142 deletions

View File

@ -1,73 +0,0 @@
import { User, Website } from '@prisma/client';
import redis from '@umami/redis-client';
import { getSession, getUser, getWebsite } from '../queries';
async function fetchWebsite(websiteId: string): Promise<Website> {
return redis.client.fetch(`website:${websiteId}`, () => getWebsite(websiteId), 86400);
}
async function storeWebsite(data: { id: any }) {
const { id } = data;
const key = `website:${id}`;
return redis.client.store(key, data, 86400);
}
async function deleteWebsite(id: any) {
return redis.client.remove(`website:${id}`);
}
async function fetchUser(id: string): Promise<User> {
return redis.client.fetch(`user:${id}`, () => getUser(id, { includePassword: true }), 86400);
}
async function storeUser(data: { id: any }) {
const { id } = data;
const key = `user:${id}`;
return redis.client.store(key, data, 86400);
}
async function deleteUser(id: any) {
return redis.client.remove(`user:${id}`);
}
async function fetchSession(id: string) {
return redis.client.fetch(`session:${id}`, () => getSession(id), 86400);
}
async function storeSession(data: { id: any }) {
const { id } = data;
const key = `session:${id}`;
return redis.client.store(key, data, 86400);
}
async function deleteSession(id: any) {
return redis.client.remove(`session:${id}`);
}
async function fetchUserBlock(userId: string) {
const key = `user:block:${userId}`;
return redis.client.get(key);
}
async function incrementUserBlock(userId: string) {
const key = `user:block:${userId}`;
return redis.client.incr(key);
}
export default {
fetchWebsite,
storeWebsite,
deleteWebsite,
fetchUser,
storeUser,
deleteUser,
fetchSession,
storeSession,
deleteSession,
fetchUserBlock,
incrementUserBlock,
enabled: !!redis.enabled,
};

View File

@ -4,7 +4,7 @@ import debug from 'debug';
import { CLICKHOUSE } from 'lib/db';
import { QueryFilters, QueryOptions } from './types';
import { OPERATORS } from './constants';
import { loadWebsite } from './load';
import { fetchWebsite } from './load';
import { maxDate } from './date';
import { filtersToArray } from './params';
@ -106,7 +106,7 @@ function getFilterParams(filters: QueryFilters = {}) {
}
async function parseFilters(websiteId: string, filters: QueryFilters = {}, options?: QueryOptions) {
const website = await loadWebsite(websiteId);
const website = await fetchWebsite(websiteId);
return {
filterQuery: getFilterQuery(filters, options),

View File

@ -1,12 +1,12 @@
import cache from 'lib/cache';
import { getSession, getUser, getWebsite } from 'queries';
import { User, Website, Session } from '@prisma/client';
import { getSession, getWebsite } from 'queries';
import { Website, Session } from '@prisma/client';
import redis from '@umami/redis-client';
export async function loadWebsite(websiteId: string): Promise<Website> {
export async function fetchWebsite(websiteId: string): Promise<Website> {
let website;
if (cache.enabled) {
website = await cache.fetchWebsite(websiteId);
if (redis.enabled) {
website = await redis.client.fetch(`website:${websiteId}`, () => getWebsite(websiteId), 86400);
} else {
website = await getWebsite(websiteId);
}
@ -18,11 +18,11 @@ export async function loadWebsite(websiteId: string): Promise<Website> {
return website;
}
export async function loadSession(sessionId: string): Promise<Session> {
export async function fetchSession(sessionId: string): Promise<Session> {
let session;
if (cache.enabled) {
session = await cache.fetchSession(sessionId);
if (redis.enabled) {
session = await redis.client.fetch(`session:${sessionId}`, () => getSession(sessionId), 86400);
} else {
session = await getSession(sessionId);
}
@ -33,19 +33,3 @@ export async function loadSession(sessionId: string): Promise<Session> {
return session;
}
export async function loadUser(userId: string): Promise<User> {
let user;
if (cache.enabled) {
user = await cache.fetchUser(userId);
} else {
user = await getUser(userId);
}
if (!user || user.deletedAt) {
return null;
}
return user;
}

View File

@ -3,7 +3,7 @@ import prisma from '@umami/prisma-client';
import moment from 'moment-timezone';
import { MYSQL, POSTGRESQL, getDatabaseType } from 'lib/db';
import { SESSION_COLUMNS, OPERATORS, DEFAULT_PAGE_SIZE } from './constants';
import { loadWebsite } from './load';
import { fetchWebsite } from './load';
import { maxDate } from './date';
import { QueryFilters, QueryOptions, SearchFilter } from './types';
import { filtersToArray } from './params';
@ -152,7 +152,7 @@ async function parseFilters(
filters: QueryFilters = {},
options: QueryOptions = {},
) {
const website = await loadWebsite(websiteId);
const website = await fetchWebsite(websiteId);
const joinSession = Object.keys(filters).find(key => SESSION_COLUMNS.includes(key));
return {

View File

@ -4,7 +4,7 @@ import { parseToken } from 'next-basics';
import { NextApiRequestCollect } from 'pages/api/send';
import { createSession } from 'queries';
import clickhouse from './clickhouse';
import { loadSession, loadWebsite } from './load';
import { fetchSession, fetchWebsite } from './load';
import { SessionData } from 'lib/types';
export async function getSession(req: NextApiRequestCollect): Promise<SessionData> {
@ -30,7 +30,7 @@ export async function getSession(req: NextApiRequestCollect): Promise<SessionDat
const { website: websiteId, hostname, screen, language } = payload;
// Find website
const website = await loadWebsite(websiteId);
const website = await fetchWebsite(websiteId);
if (!website) {
throw new Error(`Website not found: ${websiteId}.`);
@ -62,7 +62,7 @@ export async function getSession(req: NextApiRequestCollect): Promise<SessionDat
}
// Find session
let session = await loadSession(sessionId);
let session = await fetchSession(sessionId);
// Create a session if not found
if (!session) {

View File

@ -1,5 +1,4 @@
import { Prisma } from '@prisma/client';
import cache from 'lib/cache';
import { ROLES } from 'lib/constants';
import prisma from 'lib/prisma';
import { FilterResult, Role, User, UserSearchFilter } from 'lib/types';
@ -221,15 +220,5 @@ export async function deleteUser(
id: userId,
},
}),
]).then(async data => {
if (cache.enabled) {
const ids = websites.map(a => a.id);
for (let i = 0; i < ids.length; i++) {
await cache.deleteWebsite(`website:${ids[i]}`);
}
}
return data;
});
]);
}

View File

@ -1,5 +1,4 @@
import { Prisma } from '@prisma/client';
import cache from 'lib/cache';
import prisma from 'lib/prisma';
export async function createSession(data: Prisma.SessionCreateInput) {
@ -18,28 +17,20 @@ export async function createSession(data: Prisma.SessionCreateInput) {
city,
} = data;
return prisma.client.session
.create({
data: {
id,
websiteId,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
subdivision2,
city,
},
})
.then(async data => {
if (cache.enabled) {
await cache.storeSession(data);
}
return data;
});
return prisma.client.session.create({
data: {
id,
websiteId,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
subdivision2,
city,
},
});
}