add better cache for getProfileId
This commit is contained in:
committed by
Carl-Gerhard Lindesvärd
parent
7d703bcd80
commit
b02cbb2946
@@ -11,7 +11,7 @@ import {
|
||||
toISOString,
|
||||
} from '@openpanel/common';
|
||||
import type { IServiceCreateEventPayload, IServiceEvent } from '@openpanel/db';
|
||||
import { createEvent } from '@openpanel/db';
|
||||
import { createEvent, getProfileIdCached } from '@openpanel/db';
|
||||
import { getLastScreenViewFromProfileId } from '@openpanel/db/src/services/event.service';
|
||||
import { eventsQueue, findJobByPrefix, sessionsQueue } from '@openpanel/queue';
|
||||
import type {
|
||||
@@ -47,7 +47,10 @@ export async function incomingEvent(job: Job<EventsQueuePayloadIncomingEvent>) {
|
||||
};
|
||||
|
||||
// this will get the profileId from the alias table if it exists
|
||||
const profileId = body.profileId ? String(body.profileId) : '';
|
||||
const profileId = await getProfileIdCached({
|
||||
profileId: body.profileId,
|
||||
projectId,
|
||||
});
|
||||
const createdAt = new Date(body.timestamp);
|
||||
const url = getProperty('__path');
|
||||
const { path, hash, query, origin } = parsePath(url);
|
||||
|
||||
@@ -180,6 +180,7 @@ export async function createProfileAlias({
|
||||
alias: string;
|
||||
profileId: string;
|
||||
}) {
|
||||
await getProfileIdCached.clear({ profileId, projectId });
|
||||
await ch.insert({
|
||||
table: TABLE_NAMES.alias,
|
||||
format: 'JSONEachRow',
|
||||
@@ -221,7 +222,7 @@ export async function getProfileId({
|
||||
profileId,
|
||||
projectId,
|
||||
}: {
|
||||
profileId: string | undefined;
|
||||
profileId: number | string | undefined;
|
||||
projectId: string;
|
||||
}) {
|
||||
if (!profileId) {
|
||||
@@ -240,7 +241,7 @@ export async function getProfileId({
|
||||
return res[0].profile_id;
|
||||
}
|
||||
|
||||
return profileId;
|
||||
return String(profileId);
|
||||
}
|
||||
|
||||
export const getProfileIdCached = cacheable(getProfileId, 60 * 30);
|
||||
|
||||
@@ -4,11 +4,36 @@ export function cacheable<T extends (...args: any) => any>(
|
||||
fn: T,
|
||||
expireInSec: number
|
||||
) {
|
||||
return async function (
|
||||
const cachePrefix = `cachable:${fn.name}`;
|
||||
function stringify(obj: unknown): string {
|
||||
if (obj === null) return 'null';
|
||||
if (obj === undefined) return 'undefined';
|
||||
if (typeof obj === 'boolean') return obj ? 'true' : 'false';
|
||||
if (typeof obj === 'number') return String(obj);
|
||||
if (typeof obj === 'string') return obj;
|
||||
if (typeof obj === 'function') return obj.toString();
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
return '[' + obj.map(stringify).join(',') + ']';
|
||||
}
|
||||
|
||||
if (typeof obj === 'object') {
|
||||
const pairs = Object.entries(obj)
|
||||
.sort(([a], [b]) => a.localeCompare(b))
|
||||
.map(([key, value]) => `${key}:${stringify(value)}`);
|
||||
return pairs.join(':');
|
||||
}
|
||||
|
||||
// Fallback for any other types
|
||||
return String(obj);
|
||||
}
|
||||
const getKey = (...args: Parameters<T>) =>
|
||||
`${cachePrefix}:${stringify(args)}`;
|
||||
const cachedFn = async function (
|
||||
...args: Parameters<T>
|
||||
): Promise<Awaited<ReturnType<T>>> {
|
||||
// JSON.stringify here is not bullet proof since ordering of object keys matters etc
|
||||
const key = `cachable:${fn.name}:${JSON.stringify(args)}`;
|
||||
const key = getKey(...args);
|
||||
const cached = await getRedisCache().get(key);
|
||||
if (cached) {
|
||||
try {
|
||||
@@ -25,4 +50,13 @@ export function cacheable<T extends (...args: any) => any>(
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
cachedFn.getKey = getKey;
|
||||
cachedFn.clear = async function (...args: Parameters<T>) {
|
||||
const key = getKey(...args);
|
||||
console.log('[cachable] Clear', key);
|
||||
return getRedisCache().del(key);
|
||||
};
|
||||
|
||||
return cachedFn;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user